Форум программистов, компьютерный форум CyberForum.ru

Можно ли как-то в дочернем классе получить указатель родителя? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.88
newbie666
Заблокирован
09.04.2014, 17:11     Можно ли как-то в дочернем классе получить указатель родителя? #1
У меня тут появилась мыслишка
В любом классе есть так сказать скрытый указатель на самого себя - this, а можно ли как то получить в дочернем классе указатель на родительский класс?
P.S.: без всякой явной передачи в конструктор дочернего класса указателя на базовый ...

Добавлено через 12 минут
ладно, опять же забейте, просто было интересно, есть ли возможность в дочернем классе получить указатель на базовый и присвоить какое то значение по этому указателю, например:
(конструктор дочернего)
C++
1
2
3
4
Child()
{
   (Base*)this->x = 4;
}
ну конечно же так не работает
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.04.2014, 17:11     Можно ли как-то в дочернем классе получить указатель родителя?
Посмотрите здесь:

Не могу в дочернем классе вызвать protected метод C++
Как обьявить переменную в одном классе и что бы ее было видно в дочернем классе C++
C++ Запуск конструктора родителя в дочернем конструкторе
C++ Как получить ссылку на указатель или указатель на указатель в массиве?
C++ R6025 pure virtual function call при вызове метода, реализованного в дочернем классе
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ITcrusader
Эксперт C++
 Аватар для ITcrusader
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
09.04.2014, 17:23     Можно ли как-то в дочернем классе получить указатель родителя? #2
А такой вариант чем не устраивает?)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class Base
{
protected:
    int x;
};
 
class Derived: public Base
{
    Derived()
    {
        Base::x = 10;
    }
};
zss
Модератор
Эксперт С++
 Аватар для zss
5955 / 5560 / 1788
Регистрация: 18.12.2011
Сообщений: 14,209
Завершенные тесты: 1
09.04.2014, 17:32     Можно ли как-то в дочернем классе получить указатель родителя? #3
В реализации нет отдельного указателя на базовый и дочерний класс.
В дочернем классе содержатся данные базового класса как составная часть.
newbie666
Заблокирован
09.04.2014, 17:42  [ТС]     Можно ли как-то в дочернем классе получить указатель родителя? #4
Цитата Сообщение от ITcrusader Посмотреть сообщение
А такой вариант чем не устраивает?)
ну в данном случае я не устраивает что переменных может быть много.... так что лучше так:
C++
1
Child(Base *base){*this = base;};
Добавлено через 6 минут
А как лучше реализовать такое:
Есть базовый класс, есть дочерний и есть дочерний от дочернего.
[class Base, class Child1 : public Base и class Child2 : public Child1]
1. Создаю экземпляр Child1. Тоесть просто вызывается конструктор Base и потом Child1. Всё ок.
2. Теперь хочу продолжить цепь наследования именно этих классов, тоесть хочу создать экземпляр Child2, чтоб он не копировал в себя данные другой цепи, которую я создавал в п.1, а являлся бы полноценным связынным наследником...

Именно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Base
{
public:
    Base(){};
    ~Base(){};  
    int baseData;
};
 
class Child1 : public Base
{
public:
    Child1(){};
    ~Child1(){};
};
 
class Child2 : public Child1
{
public:
    Child2(){};
    ~Child2(){};
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    Child1 *child1 = new Child1;
    child1->baseData = 33;
 
    Child2 *child2 = new Child2;
    //что - то сделать
    child1->baseData = 66;
    if(child2->baseData != 66)
        std::cout << "БЕДА...:-)";
    return 0;
}
Добавлено через 2 минуты
полагаю тут нужен даункастинг типа:
C++
1
2
3
4
5
6
Child1 *child1 = new Child1;
child1->baseData = 33;
 
Child2 *child2 = new Child2;
child2 = static_cast<Child2*>(child1);
child1->baseData = 66;
да?
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
09.04.2014, 17:58     Можно ли как-то в дочернем классе получить указатель родителя? #5
Цитата Сообщение от newbie666 Посмотреть сообщение
C++
1
Child(Base *base){*this = base;};
Подозрительный код. Поясни чем он тебе поможет?
Цитата Сообщение от newbie666 Посмотреть сообщение
C++
1
2
3
4
5
6
Child1 *child1 = new Child1; 
child1->baseData = 33; 
Child2 *child2 = new Child2; //что - то сделать 
child1->baseData = 66; 
if(child2->baseData != 66) 
    std::cout << "БЕДА...:-)";
Это же разные области памяти. С чего бы им быть связанными? Ты не путай классы и объекты.

Цитата Сообщение от newbie666 Посмотреть сообщение
да?
Нет. Это разные объекты, разные области памяти.
Цитата Сообщение от newbie666 Посмотреть сообщение
C++
1
2
Child2 *child2 = new Child2;
child2 = static_cast<Child2*>(child1);
А здесь вообще потенциальная утечка.
newbie666
Заблокирован
09.04.2014, 18:01  [ТС]     Можно ли как-то в дочернем классе получить указатель родителя? #6
Цитата Сообщение от DrOffset Посмотреть сообщение
Нет.
А вот как тогда быть, например, я создал:
C++
1
Child1 *child1 = new Child1;
но потом вспомнил, ну просто например, что мне надо было создать дерево подлиннее, не до Child1, а до Child2, и тут возникает вопрос, как продолжить цепь наследования, чтоб
C++
1
Child2 *child2
являлся как бы связанным продолжением предыдущей цепи child1 ?
Тоесть как мне продлить наследование?
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
09.04.2014, 18:05     Можно ли как-то в дочернем классе получить указатель родителя? #7
Цитата Сообщение от newbie666 Посмотреть сообщение
Тоесть как мне продлить наследование?
Это наследование, но другого порядка. Его нужно в рантайме писать: организовывать честное дерево. Т.е. каждый узел хранит указатель на свои подузлы, а каждый подузел ссылается на родителя.
newbie666
Заблокирован
09.04.2014, 18:08  [ТС]     Можно ли как-то в дочернем классе получить указатель родителя? #8
Тут по сути вопрос в том, как создать много наследников от одного предка, не теряя связи с предком.
Вот цепь созданных объектов: Base->Child1->Child2
теперь я хочу создать ещё один Child2, у которого бы был родитель Child1 - Тот самый, который в основной первой цепи....
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
09.04.2014, 18:10     Можно ли как-то в дочернем классе получить указатель родителя? #9
newbie666, Тебе нужно наследование объектов, а не классов. Это представимо в виде дерева, где корень это самый базовый объект, а остальные узлы - его наследники.
newbie666
Заблокирован
09.04.2014, 18:14  [ТС]     Можно ли как-то в дочернем классе получить указатель родителя? #10
Цитата Сообщение от DrOffset Посмотреть сообщение
Тебе нужно наследование объектов, а не классов
нет, мне нужно наследование классов, т.к. я не хочу в потомках обращаться к нужным мне данным через 4 колена типа: base->child1->child2 и тд.....

Тоесть я хочу создать два потомка с разными данными, НО с одним и тем же родителем, такое в принципе реализуемо?
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
09.04.2014, 18:23     Можно ли как-то в дочернем классе получить указатель родителя? #11
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от newbie666 Посмотреть сообщение
нет, мне нужно наследование классов
Ты заблуждаешься. Классы здесь не помогут, т.к. это другая плоскость совсем, классы - это описание типа. Отношение родства между ними - родство типов. А то, что ты хочешь - это родство объектов.
Похоже без примера совсем никуда?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <vector>
#include <iostream>
 
class Base
{
public:
    Base(){};
    ~Base(){};
 
    void add(Base * child)
    {
        childs_.push_back(child);
        child->parent_ = this;
    }
    Base * parent()
    {
        return parent_;
    }
    Base * child(int idx)
    {
        return childs_[idx];
    }
 
    int baseData;
 
protected:
    std::vector<Base*> childs_;
    Base *             parent_;
};
 
class Child1 : public Base
{
public:
    Child1(Base * parent) {  parent->add(this); };
    Child1() { };
    ~Child1(){};
};
 
class Child2 : public Base
{
public:
    Child2(){};
    Child2(Base * parent) {  parent->add(this); };
    ~Child2(){};
};
 
int main(int argc, char * argv[])
{
    Child1 * ch1 = new Child1;
    ch1->baseData = 33;
 
    Child2 * ch2 = new Child2(ch1);
 
    ch1->child(0)->baseData = 66;
 
    if(ch2->baseData != 66)
        std::cout << "БЕДА...:-)";
    return 0;
}
newbie666
Заблокирован
09.04.2014, 22:30  [ТС]     Можно ли как-то в дочернем классе получить указатель родителя? #12
ok спс - дома гляну

Добавлено через 3 часа 59 минут
DrOffset, посмотрел ... ну собственно это ерунда
1.
Цитата Сообщение от DrOffset Посмотреть сообщение
1->child(0)->baseData = 66;
- здесь ты вручную устанавливаешь один параметр... А если их будет 100... а 200? Я то хотел, чтоб параметры от одного базового класса сами перетекали ко всем дочерним ...
2. Доступ к чайлдам по Id... а если 100 классов ... в ID запутаешься ....

В общем, я понял три вещи:
1. В С++ никак нельзя в дочернем классе получить указатель на собственный базовый класс. Собственно при создание дочернего класса, вызывается сперва конструктор базового класса, тоесть создаётся объект базового класса и только потом вызывается конструктор дочернего класса, тоесть создаётся сам дочерний класс, в котором нельзя получить указатель на собственный базовый класс, который где - то там в памяти создался

2. В С++ нельзя создать два и более дочерних класса от одного и того же уже созданного базового класса, чтоб изменяя какие - то значения в базовом классе как бы они менялись во всех потомках, так как они от него унаследованы.

3. По поводу всего вообще, я понял, что я делаю все правильно, хотя мне этот мой паттерн и не очень нравится. Тоесть создаю один не базовый, а общий класс, в котором создаю экземпляры всех других классов, необходимые в данном софте ну и соответственно в нём же (в общем) храню указатели на них. При создание этих всех других - передаю в ихние конструкторы указатель на общий класс, таким образом в любом классе есть доступ в любой другой, в том числе и в общий.
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
09.04.2014, 22:39     Можно ли как-то в дочернем классе получить указатель родителя? #13
Цитата Сообщение от newbie666 Посмотреть сообщение
ну собственно это ерунда
К сожалению ты путаешь теплое с мягким. От того твое недоумение.

Цитата Сообщение от newbie666 Посмотреть сообщение
Доступ к чайлдам по Id
Это индекс. Подход к индексации зависит от задачи. Абстрактно тут не решишь ничего. Это пример написанный за 1.5 минуты, для демонстрации. Озвучивай конечную конкретную задачу, чтобы получить конкретное решение.

Цитата Сообщение от newbie666 Посмотреть сообщение
В С++ никак нельзя в дочернем классе получить указатель на собственный базовый класс.
На собственный - можно. А ты предлагал на чужой (чужого объекта).

Цитата Сообщение от newbie666 Посмотреть сообщение
В С++ нельзя создать два и более дочерних класса от одного и того же базового класса, чтоб изменяя какие - то значения в базовом классе как бы они менялись во всех потомках, так как они от него унаследованы.
Ты опять путаешь классы и объекты. Приведи пример хотя бы одного языка с ООП, в котором так можно.

Цитата Сообщение от newbie666 Посмотреть сообщение
По поводу всего вообще, я понял, что я делаю все правильно, хотя мне этот мой паттерн и не очень нравится.
Этот - это какой?

Цитата Сообщение от newbie666 Посмотреть сообщение
При создание этих всех других - передаю в ихние конструкторы указатель на общий класс
Ты не заметил, что в моем примере та же идея используется?

Добавлено через 2 минуты
Цитата Сообщение от newbie666 Посмотреть сообщение
- здесь ты вручную устанавливаешь один параметр...
Я же перепечатал один в один твой пример. Ты либо формулируй задачу точно, либо не придирайся к абстрактным примерам, которые даны на абстрактный вопрос.
newbie666
Заблокирован
09.04.2014, 22:48  [ТС]     Можно ли как-то в дочернем классе получить указатель родителя? #14
из всего вышесказанного интересно следующее:
Цитата Сообщение от DrOffset Посмотреть сообщение
В С++ никак нельзя в дочернем классе получить указатель на собственный базовый класс.
На собственный - можно. А ты предлагал на чужой (чужого объекта).
Смотри, class Base , class Child : public base. Child *child = new Child; Как получить указатель на базовый класс экземпляра child класса Child?
Мне это нужно было для того, чтоб попробовать присвоить указатель базового класса одного экземпляра к базовому классу другого экземпляра, чтоб как бы добиться заветной цели - породнить их по батьке

Цитата Сообщение от DrOffset Посмотреть сообщение
ы опять путаешь классы и объекты. Приведи пример хотя бы одного языка с ООП, в котором так можно.
хрен его знает, не знаю таких языков, но надеялся, что в С++ как то можно так извернуться ...

Цитата Сообщение от DrOffset Посмотреть сообщение
Этот - это какой?
да никакой - просто самопридуманный ))))

Цитата Сообщение от DrOffset Посмотреть сообщение
Ты не заметил, что в моем примере та же идея используется?
да, я тебе, или не тебе - в похожей теме сегодня говорил ....
Так что мой вариант и есть оптимальный наверное, хотя мне он не очень нравится ...
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
09.04.2014, 22:48     Можно ли как-то в дочернем классе получить указатель родителя? #15
И еще у тебя похоже проблемы с пониманием что же такое наследование в С++. Вот на мой взгляд годная статья с примерами как располагаются объекты в памяти при наследовании.
newbie666
Заблокирован
09.04.2014, 22:52  [ТС]     Можно ли как-то в дочернем классе получить указатель родителя? #16
Цитата Сообщение от DrOffset Посмотреть сообщение
еще у тебя похоже проблемы с пониманием что же такое наследование в С++.
да не, проблем нет... Есть сожаление о некоторых не реализованных возможностях С++, которые часто обсуждаются на разных форумах - например вот мой вопрос про два наследника от одного класса и например - виртуалные конструкторы ... Ну да ладно....
Статью гляну - спс.
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
09.04.2014, 23:04     Можно ли как-то в дочернем классе получить указатель родителя? #17
newbie666, посмотри статью. Там есть ответы на эти вопросы.
Цитата Сообщение от newbie666 Посмотреть сообщение
Смотри, class Base , class Child : public base. Child *child = new Child; Как получить указатель на базовый класс экземпляра классы child ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Base
{ };
class Child : public Base
{
public:
    Child() : Base() // Объект типа Base часть типа Child
    {}
};
 
int main()
{
    Child * child = new Child;
    Base  * base  = child; // автоматически приводится по правилам языка
}
Это указатель на его базовый класс. Базовый класс не шарится между потомками (и не должен), потому что у каждого потока свой экземпляр базового класса при создании объекта.

Добавлено через 8 минут
Цитата Сообщение от newbie666 Посмотреть сообщение
Есть сожаление о некоторых не реализованных возможностях С++
newbie666, слушай, ну правда. Это же уже не смешно Таких возможностей нет нигде, это смешивание кислого и пресного.
Давай на пальцах:
Есть Чертеж базовой модели самолета( чертеж B).
Есть модель, спроектированная на базе этого чертежа, назовем ее чертеж А.
Есть еще одна модель, усовершенствованная версия А, назовем чертеж А1.
Теперь мы строим экземпляр по чертежу А, получаем изделие а.
Потом строим экземпляр по чертежу А1, получаем изделие а1.
Теперь смотри, оба самолета взлетают и у a1 птица попадает в турбину и один из двигателей отказывает. Турбина является базовой конструкцией, которая сделана по чертежу B. Значит ли это, что у самолета а тоже сейчас произойдет возгорание этого двигателя? Конечно нет! Вот и ответ. Конструктивно они похожи (сделаны по одному базовому чертежу), однако изменяется состояние у каждого независимо (потому что это разные экземпляры).
newbie666
Заблокирован
09.04.2014, 23:11  [ТС]     Можно ли как-то в дочернем классе получить указатель родителя? #18
Цитата Сообщение от DrOffset Посмотреть сообщение
Это указатель на его базовый класс.
Ну вот допустим я получил у двух РАЗНЫХ экземпляров дочерних классов указатель на базовый класс. Можно как то связать эти указатели или присвоит одному указателю - другой.... чтоб связать два дочерних базовым? Тоесть чтоб я мог у любого дочернего получить указатель на базовый, поменять какую - то переменную в базовом классе и, проверив её в другом экземпляре дочернего класса, убедится что она идентична переменной в первом экземпляре класса, т.к. они связанны общий базовым классом ....

P.S.: ладно- надоело :) спасибо.. я спать ))))
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
09.04.2014, 23:35     Можно ли как-то в дочернем классе получить указатель родителя? #19
Цитата Сообщение от newbie666 Посмотреть сообщение
Тоесть чтоб я мог у любого дочернего получить указатель на базовый, поменять какую - то переменную в базовом классе и, проверив её в другом экземпляре дочернего класса, убедится что она идентична переменной в первом экземпляре класса, т.к. они связанны общий базовым классом ....
В том и фишка, что подобное отношение - это не наследование типов. Смотри пример с самолетами.
Наследуются типы, а значение ты меняешь у объекта. Вдумайся в это. Вот и получается, что чтобы такое организовать нужно иметь, например, два экземпляра, которые ссылаются на базовый:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Base
{
public:
    Base() {}
};
 
class Child1
{
public:
    Child1(Base * p) : parent(p) {}
 
    Base * parent;
};
 
class Child2
{
public:
    Child2(Base * p) : parent(p) {}
 
    Base * parent;
};
 
int main()
{
    Base * base = new Base;
 
    Child1 * child1 = new Child1(base);
    Child2 * child2 = new Child2(base);
}
Внеся ссылку на базовый экземпляр мы обеспечили доступ к общему объекту (заметь, объекту). наследования тут пока вообще нет (специально).
А наследование типов здесь понадобится уже затем, чтобы получить возможность в качестве базового класса указывать один из потомков (т.к. все они будут приводимы к базе). Получаем вот:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Base
{
public:
    Base(Base * p = 0) : parent(p) {}
 
    Base * parent;
};
 
class Child1 : public Base
{
public:
    Child1(Base * p) : Base(p) {}
};
 
class Child2 : public Base
{
public:
    Child2(Base * p) : Base(p) {}
};
 
int main()
{
    Base * base = new Base;
 
    Child1 * child1 = new Child1(base);
    Child2 * child2 = new Child2(child1);
 
    child2->parent; // это child1
    child2->parent->parent; // это base
}
То же самое, что и мой предыдущий пример. И это именно то, что ты описывал. Остальные вещи уточнятся должны уже исходя из конкретной задачи.

Добавлено через 3 минуты
Цитата Сообщение от newbie666 Посмотреть сообщение
виртуалные конструкторы
Virtual Constructor
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.04.2014, 08:26     Можно ли как-то в дочернем классе получить указатель родителя?
Еще ссылки по теме:

C++ Ошибка в дочернем классе
C++ Перегрузка fstream в дочернем классе
Изменение информации в дочернем классе, через ссылку C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
newbie666
Заблокирован
10.04.2014, 08:26  [ТС]     Можно ли как-то в дочернем классе получить указатель родителя? #20
ну у меня всё сейчас так же и реализовано, я вообще поднял тут уже несколько тредов только лишь для того, чтоб выяснить возможность подомных манипуляций с одним базовым классом, а нужно мне это всё чисто для удобства работы, так то похрену.....
Цитата Сообщение от DrOffset Посмотреть сообщение
ild2->parent->parent; // это base
- видишь, много стрелочек -> Тоесть неудобно, я хотел работать вообще без стрелочек, еслиб данные были как бы унаследованны в в класс.... Ладно, спасибо за потраченное время ... Оставлю у себя всё как есть ... (делаю супер online 3D Shooter / с элементами стратегии типа Ascendancy (DOS) )
Yandex
Объявления
10.04.2014, 08:26     Можно ли как-то в дочернем классе получить указатель родителя?
Ответ Создать тему
Опции темы

Текущее время: 07:47. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru