Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Два класса


Автор: JAnty 29.3.2007, 11:59
Вот:
Код

class c_CL1
{
public:
AnsiString str;
/*
...
*/
c_CL1(void); // конструктор, в нём str становится str="Привет";
};
///////////////////////////////////////////////
class c_CL2 : public c_CL1
{
public:
// AnsiString str;
/*
...
*/
c_CL2(void); // конструктор
};

Код

c_CL1 CL1;
c_CL2 CL2; 
main()
{
printf("%s",CL2.str); // не получается.
printf("%s",CL1.str); // получается.
}

А если во 2м классе объявлю AnsiString str и в конструкторе присвою "Привет", то получится.
Чо за фигня? /*Консольное написал для примера, пишу в Билдере.*/


Автор: Greeen 29.3.2007, 12:46
Код

#include <iostream>

class class1
{
public:
    int a;
    class1() { a = 5; }
};

class class2 : public class1
{
public:
    class2() {}
};

void main()
{
    class1 cl1;
    class2 cl2;
    std::cout << cl1.a;
    std::cout << cl2.a;
}

Все нормально, вывод - 55 (VS 2005)

Автор: JAnty 29.3.2007, 12:56
А Билдер не хочет выводить.

Автор: maxim1000 29.3.2007, 13:00
когда в потомке объявляется переменная, совпадающая по имени с переменной из базового класса, начинается путанница:
когда объект рассматривается, как базовый - str означает c_CL1::str
когда как потомок - c_CL2::str
вот и получается:
----- в случае с одним объявлением
1. при создании потомка вызывается конструктор предка, он заполняет переменную c_CL1::str
2. первый printf оперирует c_CL1::str
3. второй - тоже, потому что она наследуется
----- в случае с двумя объявлениями
1. при создании потомка вызывается конструктор предка, внутри этого конструктора объект рассматривается, как c_CL1, потому используется c_CL1::str
2. первый printf тоже рассматривает объект класса c_CL1::str, потому и работает с заполненной переменной
3. второй printf работает с c_CL2, в нём объявлена вторая переменная str, которая перекрывает первую (т.к. имена у них совпадают), так что printf выводит c_CL2::str

P.S.
не стоит объявлять переменные с одним и тем же именем в предках и потомках без хорошей причины, ибо запутывает
буквально вчера ловили связанный с этим глюк (не наш smile)...

Автор: Greeen 29.3.2007, 13:06
JAnty, Билдер на свалку  smile 

Автор: Fazil6 29.3.2007, 13:08
Цитата(JAnty @  29.3.2007,  11:59 Найти цитируемый пост)
А если во 2м классе объявлю AnsiString str и в конструкторе присвою "Привет", то получится.Чо за фигня? /*Консольное написал для примера, пишу в Билдере.*/

все должно выводится. Специально даже попроверил - все выводится...

Автор: JAnty 29.3.2007, 13:09
Мда, в этом ООП сам чёрт ногу сломит.
Чтом я ногу не сломил, поменял названия да и всё, проподи оно всё проподом. smile

Добавлено через 2 минуты и 37 секунд
В новом проекте и у меня выводится, а в моём нет! Так что пришлось менять переменную.

Автор: Fazil6 29.3.2007, 13:13
maxim1000, и что следует из того, что ты написал?

Автор: _stranger_ 29.3.2007, 13:13
Код

printf("%s",CL2.str); // не получается.
printf("%s",CL1.str); // получается.

JAnty что значит не получается? какие ошибки? что выводит?

Автор: maxim1000 29.3.2007, 13:20
Цитата(Fazil6 @  29.3.2007,  13:13 Найти цитируемый пост)
maxim1000, и что следует из того, что ты написал?

ну, в основном, это было написано в ответ на вопрос "почему?" (приблизительно цитирование smile)
вот я и попытался объяснить, почему всё происходит так, как оно происходит
ну а в качестве следствия можно рассматривать совет, что так делать в большинстве случаев не стоит...

Автор: JAnty 29.3.2007, 13:30
Я всё понял, но не совсем, дело в том что у меня нет конструктора (я слегка приукрасил), у меня есть функция выполняющая эти действия (присваивает нужные значения), вот и ошибка.
Раз переменная открытая, то она должна быть видна в обоях классах, но нет, видна но без знасения.
Например как уменя:
Код

#include <iostream>

class class1
{
public:
    int a;
    CONSTRUCTOR() { a = 5; }
};

class class2 : public class1
{
public:
    class2() {}
};

void main()
{
    class1 cl1;
    class2 cl2;
    class1.CONSTRUCTOR() ;
    std::cout << cl1.a;
    std::cout << cl2.a;
}



Выведет 5 и всё;

Добавлено через 7 минут и 1 секунду
Приходится дописывать ещё и 
class2.CONSTRUCTOR() ;

переменная одна, зачем ей 2 раза присваивать значение, а если мне надо её прочесть из одного класса а записать в другом, то неполучится, т.к а одна для одного класса, а другая для другого.

Автор: apook 29.3.2007, 13:39
как так пишешь
Код

    class1.CONSTRUCTOR() ;

работает что-ли

Автор: Fazil6 29.3.2007, 13:40
Код

 class1.CONSTRUCTOR() ; 

хм... оригинально... У тебя это компиллируется?


А вообще

Цитата(JAnty @  29.3.2007,  13:30 Найти цитируемый пост)
Раз переменная открытая, то она должна быть видна в обоях классах, но нет, видна но без знасения.

по твоему примеру если предположить cl1.CONSTRUCTOR() ; , то это ведь для первого объекта. С чего во втором объекте твоя переменная должна инициализироваться? Вот и нет во втором значения

Автор: Greeen 29.3.2007, 13:41
И зачем такие извращения  smile 

Автор: Fazil6 29.3.2007, 13:42
Цитата(JAnty @  29.3.2007,  13:30 Найти цитируемый пост)
переменная одна, зачем ей 2 раза присваивать значение, а если мне надо её прочесть из одного класса а записать в другом, то неполучится, т.к а одна для одного класса, а другая для другого.

ты бы проводил различия между классами и их объектами. У каждого объекта класса свои переменные, и когда ты в одном меняешь, то в другом естественно ничего не меняется

Автор: apook 29.3.2007, 13:53
В первом классе то что называешь СONSTRUCTOR ни фига не
конструктор
Код

    class1() { a = 5; }
 
вот конструктор
Код

void main()
{
    class1 cl1;
    class2 cl2;
    std::cout << cl1.a << endl;
    std::cout << cl2.a << endl;

}

так все будет работать

Автор: JAnty 29.3.2007, 13:56
Цитата(Fazil6 @  29.3.2007,  13:42 Найти цитируемый пост)
У каждого объекта класса свои переменные, и когда ты в одном меняешь, то в другом естественно ничего не меняется 


Теперь уже понял, больше небуду об стенку головой. 
                                                                              (South Park) smile

Добавлено через 3 минуты и 31 секунду
Цитата(apook @  29.3.2007,  13:53 Найти цитируемый пост)
В первом классе то что называешь СONSTRUCTOR ни фига не
конструктор

Я знаю, просто объект класса глобальный и его настоящий конструктор делает много всего большого и прога на время подвисает, а мой (типо) конструктор вызывается мной перед появлением надписи Загрузка...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)