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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.88
newbie666
Заблокирован
#1

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

09.04.2014, 17:11. Просмотров 2589. Ответов 40
Метки нет (Все метки)

У меня тут появилась мыслишка
В любом классе есть так сказать скрытый указатель на самого себя - this, а можно ли как то получить в дочернем классе указатель на родительский класс?
P.S.: без всякой явной передачи в конструктор дочернего класса указателя на базовый ...

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

Как обьявить переменную в одном классе и что бы ее было видно в дочернем классе - C++
У меня есть основной класс с названием Root один из его членов наследует дочерний класс SubRoot. Скажите как объявить, что бы один из...

Запуск конструктора родителя в дочернем конструкторе - C++
Вобщем имеется два класса class Coma{ public: double x,y; Coma(){ x=0; y=0; } Coma(int x, int y){ this->x=x;

Как получить ссылку на указатель или указатель на указатель в массиве? - C++
В процессе реализации сортировки пузырьком натолкнулся на такую проблему: как поменять значения указателей, передаваемых в функцию. Если...

Ошибка в дочернем классе - C++
Не могу найти ошибку в дочернем классе, возможно не правильно написать main Задание и код: Код нужно переписывать в сообщение Только...

Перегрузка fstream в дочернем классе - C++
h class Child:public StudentsBD{ friend fstream &operator<<( fstream& , string & ); friend fstream &operator>>( fstream& , string...

Изменение информации в дочернем классе, через ссылку - C++
Подскажите, есть класс class Class1 В конструкторе я создаю структуру, которая будет хранить в себе ссылки на все классы...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
ITcrusader
Эксперт C++
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;
    }
};
1
zss
Модератор
Эксперт С++
6382 / 5947 / 1927
Регистрация: 18.12.2011
Сообщений: 15,264
Завершенные тесты: 1
09.04.2014, 17:32 #3
В реализации нет отдельного указателя на базовый и дочерний класс.
В дочернем классе содержатся данные базового класса как составная часть.
1
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;
да?
0
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
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);
А здесь вообще потенциальная утечка.
1
newbie666
Заблокирован
09.04.2014, 18:01  [ТС] #6
Цитата Сообщение от DrOffset Посмотреть сообщение
Нет.
А вот как тогда быть, например, я создал:
C++
1
Child1 *child1 = new Child1;
но потом вспомнил, ну просто например, что мне надо было создать дерево подлиннее, не до Child1, а до Child2, и тут возникает вопрос, как продолжить цепь наследования, чтоб
C++
1
Child2 *child2
являлся как бы связанным продолжением предыдущей цепи child1 ?
Тоесть как мне продлить наследование?
0
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
09.04.2014, 18:05 #7
Цитата Сообщение от newbie666 Посмотреть сообщение
Тоесть как мне продлить наследование?
Это наследование, но другого порядка. Его нужно в рантайме писать: организовывать честное дерево. Т.е. каждый узел хранит указатель на свои подузлы, а каждый подузел ссылается на родителя.
1
newbie666
Заблокирован
09.04.2014, 18:08  [ТС] #8
Тут по сути вопрос в том, как создать много наследников от одного предка, не теряя связи с предком.
Вот цепь созданных объектов: Base->Child1->Child2
теперь я хочу создать ещё один Child2, у которого бы был родитель Child1 - Тот самый, который в основной первой цепи....
0
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
09.04.2014, 18:10 #9
newbie666, Тебе нужно наследование объектов, а не классов. Это представимо в виде дерева, где корень это самый базовый объект, а остальные узлы - его наследники.
1
newbie666
Заблокирован
09.04.2014, 18:14  [ТС] #10
Цитата Сообщение от DrOffset Посмотреть сообщение
Тебе нужно наследование объектов, а не классов
нет, мне нужно наследование классов, т.к. я не хочу в потомках обращаться к нужным мне данным через 4 колена типа: base->child1->child2 и тд.....

Тоесть я хочу создать два потомка с разными данными, НО с одним и тем же родителем, такое в принципе реализуемо?
0
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
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;
}
1
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. По поводу всего вообще, я понял, что я делаю все правильно, хотя мне этот мой паттерн и не очень нравится. Тоесть создаю один не базовый, а общий класс, в котором создаю экземпляры всех других классов, необходимые в данном софте ну и соответственно в нём же (в общем) храню указатели на них. При создание этих всех других - передаю в ихние конструкторы указатель на общий класс, таким образом в любом классе есть доступ в любой другой, в том числе и в общий.
0
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
09.04.2014, 22:39 #13
Цитата Сообщение от newbie666 Посмотреть сообщение
ну собственно это ерунда
К сожалению ты путаешь теплое с мягким. От того твое недоумение.

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

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

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

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

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

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

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

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

Цитата Сообщение от DrOffset Посмотреть сообщение
Ты не заметил, что в моем примере та же идея используется?
да, я тебе, или не тебе - в похожей теме сегодня говорил ....
Так что мой вариант и есть оптимальный наверное, хотя мне он не очень нравится ...
0
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
09.04.2014, 22:48 #15
И еще у тебя похоже проблемы с пониманием что же такое наследование в С++. Вот на мой взгляд годная статья с примерами как располагаются объекты в памяти при наследовании.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.04.2014, 22:48
Привет! Вот еще темы с ответами:

Использование переменных базового класса в дочернем классе - C++
Доброго времени суток. Подскажите пожалуйста как в классе SumbString работать с переменными(string s;int z ; ) класса factory ? Мне...

Не могу в дочернем классе вызвать protected метод - C++
Всем привет! Начал писать одну программку, и столкнулся со следующей проблемой: у меня пока 2 класса: MemObject и Vector, где Vector...

R6025 pure virtual function call при вызове метода, реализованного в дочернем классе - C++
Всем привет. Вот такая ошибка у меня возникает при вызове метода, который реализован в дочернем классе, но потом он почему-то становится...

Как в main() создать указатель на функцию, которая находится в классе? - C++
В этом примере как определить указатель на функцию F()? class A { public: bool F(int &amp;a, int &amp;b) { return a&lt;b; } }; int...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.04.2014, 22:48
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru