Здравствуйте, blacksun, Вы писали:
B>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
Здравствуйте, breee breee, Вы писали:
BB>А твой пример можно переписать вот так: http://ideone.com/mblKt BB>В этом случае Aggregated::operator= вызван не будет. Т.е. для объекта производного класса мы можем использовать оба оператора. Единственная разница — для оператора производного класса можно использовать синтаксический сахар — запись d1 = d2, вместо d1.operator=(d2), а в остальном принципиальной разницы между ними нет никакой.
Можно проще показать:
struct Base { };
struct Derived : Base
{
using Base::operator=;
};
int main()
{
Base b;
Derived d;
d = b;
}
Здравствуйте, blacksun, Вы писали:
B>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
Ну, во-первых, не наследуются функции-члены, автоматически генерируемые компилятором: копирующий оператор присваивания и деструктор; а во-вторых, не наследуются конструкторы, причем, не только автоматически генерируемые — копирующий и по умолчанию — а, наверное, можно сказать, что все.
Здравствуйте, rg45, Вы писали:
R>Ну, во-первых, не наследуются функции-члены, автоматически генерируемые компилятором: копирующий оператор присваивания и деструктор; а во-вторых, не наследуются конструкторы, причем, не только автоматически генерируемые — копирующий и по умолчанию — а, наверное, можно сказать, что все.
Неправда ваша про оператор. Наследуется он на общих основаниях — 13.5/6 "Operator functions are inherited in the same manner as other base class functions"
Если не поможет, будем действовать током... 600 Вольт (C)
Здравствуйте, rg45, Вы писали:
R>То, что копирующий оператор присваивания базового класса доступен из производного, вовсе не означает, что он наследуется. Ты еще разок внимательно взгляни на приведенный мной пример и ответь на один вопрос: откуда вызвается Aggregated::operator=? (То, что он вызывается очевидно из секции output). Вариант ответа на этот вопрос только один: из сгенерированного компилятором копирующего оператора присваивания: Derived::operator=. А это означает, что производный класс имеет свой сообственный копирующий оператор присваивания, который скрывает копирующий оператор присваивания базового. Скрывает, а не наследует, понимаешь? И, на всякий случай, еще разок сошлюсь на стандарт: п.13.5.3/1.
А твой пример можно переписать вот так: http://ideone.com/mblKt
В этом случае Aggregated::operator= вызван не будет. Т.е. для объекта производного класса мы можем использовать оба оператора. Единственная разница — для оператора производного класса можно использовать синтаксический сахар — запись d1 = d2, вместо d1.operator=(d2), а в остальном принципиальной разницы между ними нет никакой.
Здравствуйте, rg45, Вы писали:
R>... а во-вторых, не наследуются конструкторы, причем, не только автоматически генерируемые — копирующий и по умолчанию — а, наверное, можно сказать, что все.
В C++0x конструкторы могут наследоваться (подробнее здесь, или 12.9 в драфте), хотя уже поступают предложения об удалении этой возможности.
Юрий Жмеренецкий:
ЮЖ>В C++0x конструкторы могут наследоваться (подробнее здесь, или 12.9 в драфте), хотя уже поступают предложения об удалении этой возможности.
Здравствуйте, wvoquine, Вы писали:
B>>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
W>Приватные члены, типа, не рассматриваются вообще?
Они не доступны, но они наследуются. Для того, чтобы в этом убедиться, достаточно какую-нибудь функцию объявить другом базового класса. Вот пример: http://ideone.com/1Twca
Здравствуйте, blacksun, Вы писали:
AG>>дружба не наследуется.
B>А как же это работает тогда: B>...
"Дружба не наследуется" нужно понимать так, что друзья базового класса не являются автоматически друзьями производных. В приведенном тобой примере друг базового класса получает доступ к закрытому члену базового же класса, так что все правильно. Доступ же к закрытым членам производного класса закрыт для друга базового:
class FT
{
private:
int m_x;
friend int main();
};
class FT2 : public FT
{
private:
int m_y;
};
int main()
{
FT2 ft2;
ft2.m_x = 555; //Ok: 'FT::m_x' is private and 'main' is friend of 'FT'
ft2.m_y = 777; //error: 'FT2::m_y' is private and 'main' is not friend of 'FT2'
}
Здравствуйте, wvoquine, Вы писали:
W>Здравствуйте, blacksun, Вы писали:
B>>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
W>Приватные члены, типа, не рассматриваются вообще?
К ним нет доступа, но они скорее наследуются, так как в объектах производного класса присутствуют.
Здравствуйте, blacksun, Вы писали:
B>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
MX>Неправда ваша про оператор. Наследуется он на общих основаниях — 13.5/6 "Operator functions are inherited in the same manner as other base class functions"
Судя по обсуждению по ссылке из второго сообщения и спецификации, наследуется все таки все.
Здравствуйте, -MyXa-, Вы писали:
MX>Здравствуйте, rg45, Вы писали:
R>>Ну, во-первых, не наследуются функции-члены, автоматически генерируемые компилятором: копирующий оператор присваивания и деструктор; а во-вторых, не наследуются конструкторы, причем, не только автоматически генерируемые — копирующий и по умолчанию — а, наверное, можно сказать, что все.
MX>Неправда ваша про оператор. Наследуется он на общих основаниях — 13.5/6 "Operator functions are inherited in the same manner as other base class functions"
В п. 13.5/6 сформулировано общее правило для всех оператов, включая некопирующие операторы присваивания. Оператор же копируюющего присваивания — это специальная функция, в определенных случаях генерируемая компилятором. О копирующем операторе присваивания в п.13.5.3/1 сказано следующее:
An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user (12.8), a base class assignment operator is always hidden by the copy assignment operator of the derived class.
И вот пример, подтверждающий это: http://ideone.com/ngLcn. Как видно из этого примера, в производном классе копмилятор автоматически генерирует оператор копирующего присваивания, который, кроме того что вызывает копирующий оператор присваивания базового класса, также вызывает копирующий оператор присваивания агрегируемого члена.
Здравствуйте, blacksun, Вы писали:
B>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
Здравствуйте, blacksun, Вы писали:
B>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, -MyXa-, Вы писали:
MX>>Здравствуйте, rg45, Вы писали:
R>>>Ну, во-первых, не наследуются функции-члены, автоматически генерируемые компилятором: копирующий оператор присваивания и деструктор; а во-вторых, не наследуются конструкторы, причем, не только автоматически генерируемые — копирующий и по умолчанию — а, наверное, можно сказать, что все.
MX>>Неправда ваша про оператор. Наследуется он на общих основаниях — 13.5/6 "Operator functions are inherited in the same manner as other base class functions"
R>В п. 13.5/6 сформулировано общее правило для всех оператов, включая некопирующие операторы присваивания. Оператор же копируюющего присваивания — это специальная функция, в определенных случаях генерируемая компилятором. О копирующем операторе присваивания в п.13.5.3/1 сказано следующее: R>
R>An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user (12.8), a base class assignment operator is always hidden by the copy assignment operator of the derived class.
Имхо, все-таки наследуется:
#include <iostream>
class Base
{
public:
Base& operator=(const Base&)
{
std::cout << "Base::operator=" << std::endl;
return *this;
}
};
class Derived : public Base
{
public:
void func()
{
Base::operator=(*this);
}
};
int main()
{
Derived d1, d2;
d2 = d1;
}
Здравствуйте, breee breee, Вы писали:
BB>>Из производного класса можно свободно вызывать оператор присваивания базового.
То, что копирующий оператор присваивания базового класса доступен из производного, вовсе не означает, что он наследуется. Ты еще разок внимательно взгляни на приведенный мной пример и ответь на один вопрос: откуда вызвается Aggregated::operator=? (То, что он вызывается очевидно из секции output). Вариант ответа на этот вопрос только один: из сгенерированного компилятором копирующего оператора присваивания: Derived::operator=. А это означает, что производный класс имеет свой сообственный копирующий оператор присваивания, который скрывает копирующий оператор присваивания базового. Скрывает, а не наследует, понимаешь? И, на всякий случай, еще разок сошлюсь на стандарт: п.13.5.3/1.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, breee breee, Вы писали:
BB>>>Из производного класса можно свободно вызывать оператор присваивания базового.
R>То, что копирующий оператор присваивания базового класса доступен из производного, вовсе не означает, что он наследуется.
А по-моему означает именно это
R>Ты еще разок внимательно взгляни на приведенный мной пример и ответь на один вопрос: откуда вызвается Aggregated::operator=? (То, что он вызывается очевидно из секции output). Вариант ответа на этот вопрос только один: из сгенерированного компилятором копирующего оператора присваивания: Derived::operator=. А это означает, что производный класс имеет свой сообственный копирующий оператор присваивания, который скрывает копирующий оператор присваивания базового. Скрывает, а не наследует, понимаешь? И, на всякий случай, еще разок сошлюсь на стандарт: п.13.5.3/1.
Ты так говоришь, как будто "скрывает" и "наследует" это взаимоисключающие вещи. По-моему, они ортогональны. Да, он скрывается оператором производного класса, но все еще доступен в нем, а значит наследуется.
В таком примере кода поле i тоже скрывается в производном классе.
#include <iostream>
struct A
{
int i;
};
struct B : A
{
int i;
};
int main()
{
B b;
b.i = 10;
b.A::i = 20;
std::cout << sizeof(b) << std::endl;
std::cout << b.i << " ; " << b.A::i << std::endl;
}
Здравствуйте, breee breee, Вы писали:
BB>Здравствуйте, rg45, Вы писали:
R>>То, что копирующий оператор присваивания базового класса доступен из производного, вовсе не означает, что он наследуется. Ты еще разок внимательно взгляни на приведенный мной пример и ответь на один вопрос: откуда вызвается Aggregated::operator=? (То, что он вызывается очевидно из секции output). Вариант ответа на этот вопрос только один: из сгенерированного компилятором копирующего оператора присваивания: Derived::operator=. А это означает, что производный класс имеет свой сообственный копирующий оператор присваивания, который скрывает копирующий оператор присваивания базового. Скрывает, а не наследует, понимаешь? И, на всякий случай, еще разок сошлюсь на стандарт: п.13.5.3/1.
BB>Ты так говоришь, как будто "скрывает" и "наследует" это взаимоисключающие вещи. По-моему, они ортогональны. Да, он скрывается оператором производного класса, но все еще доступен в нем, а значит наследуется. BB>В таком примере кода поле i тоже скрывается в производном классе. BB>Значит, по-твоему, оно не наследуется?
BB>А твой пример можно переписать вот так: http://ideone.com/mblKt BB>В этом случае Aggregated::operator= вызван не будет. Т.е. для объекта производного класса мы можем использовать оба оператора. Единственная разница — для оператора производного класса можно использовать синтаксический сахар — запись d1 = d2, вместо d1.operator=(d2), а в остальном принципиальной разницы между ними нет никакой.
Здравствуйте, wvoquine, Вы писали:
W>Здравствуйте, blacksun, Вы писали:
B>>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
W>Приватные члены, типа, не рассматриваются вообще?
К приватным нет прямого доступа, но это не значит что они не наследуются.
class A
{
int m_x;
public:
void set_x(int x)
{
m_x = x;
}
void print_x()
{
std::cout << m_x << std::endl;
}
};
class B : public A
{
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
b.set_x(11111);
b.print_x();
return 0;
}
Здравствуйте, Alexander G, Вы писали:
AG>Здравствуйте, blacksun, Вы писали:
B>>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
AG>дружба не наследуется.
А как же это работает тогда:
class FT;
class FT2;
class BestFr
{
public:
void func(FT2 & ft);
};
class FT
{
int m_x;
friend class BestFr;
//friend void BestFr::func(FT &);
};
class FT2 : public FT
{
};
void BestFr::func(FT2 & ft)
{
ft.m_x = 99;
}
int _tmain(int argc, _TCHAR* argv[])
{
FT2 ft2;
BestFr bf;
bf.func(ft2); // после вызова в ft2.m_x лежит 99 !!!return 0;
}
Здравствуйте, blacksun, Вы писали:
B>Здравствуйте, Alexander G, Вы писали:
AG>>Здравствуйте, blacksun, Вы писали:
B>>>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
AG>>дружба не наследуется.
B>А как же это работает тогда:
B>
B>class FT;
B>class FT2;
B>class BestFr
B>{
B>public:
B> void func(FT2 & ft);
B>};
B>class FT
B>{
B> int m_x;
B> friend class BestFr;
B> //friend void BestFr::func(FT &);
B>};
B>class FT2 : public FT
B>{
B>};
B>void BestFr::func(FT2 & ft)
B>{
B> ft.m_x = 99;
B>}
B>int _tmain(int argc, _TCHAR* argv[])
B>{
B> FT2 ft2;
B> BestFr bf;
B> bf.func(ft2); // после вызова в ft2.m_x лежит 99 !!!
B> return 0;
B>}
B>
Наследование интерфейса, нафиг!
Похоже, наследование приватных данных проходит как часть наследования реализации.
Но дружба ломает эту парадигму, и сама криво наследуется.
Видимо, друга базового класса нужно понимать как нечто вроде части реализации базового класса.
R>"Дружба не наследуется" нужно понимать так, что друзья базового класса не являются автоматически друзьями производных. В приведенном тобой примере друг базового класса получает доступ к закрытому члену базового же класса, так что все правильно. Доступ же к закрытым членам производного класса закрыт для друга базового...
Наверное, лучше это всё же описывается в терминах наследования реализации/наследования интерфейса. Тогда это не похоже на какую-то дыру
Здравствуйте, blacksun, Вы писали:
B>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
А не следует ли на такой вопрос отвечать вопросом: What's In Class?
а помоему это идиотский вопрос можно хорошего кандидата отсеять
а какого нибудь зубрилку ботаника взять
я бы просил написать код основных структур данных списки деревья плюс
по специальности если он tcp/ip кодер то написать сервер клиент с определенными
тех требованиями к нагрузке и смотрел бы на качество кода на стиль
на поведение интересный человек увлечен своим делом или нет спросил бы есть
ли у него свои проекты чтоб показал мне же с ним работать придется
а спрашивать такую ересь чистой воды бредятина ну знает он и что
тот кто не знает прочитает и через пять минут тоже будет знать
вообще не показатель этот вопрос
On 11.06.2011 0:40, blacksun wrote:
> Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все > наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
On 11.06.2011 1:49, rg45 wrote:
> > Ну, во-первых, не наследуются функции-члены, автоматически генерируемые > компилятором: копирующий оператор присваивания и деструктор; а во-вторых, не > наследуются конструкторы, причем, не только автоматически генерируемые — > копирующий и по умолчанию — а, наверное, можно сказать, что все.
Да просто ВСЕ конструкторы и деструктор. И оператор присваивания.
Не важно, как они сделаны, автоматически или вручную.
Здравствуйте, MasterZiv, Вы писали:
MZ>On 11.06.2011 0:40, blacksun wrote:
>> Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все >> наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
MZ>Конструкторы, деструктор, оператор присваивания.
Конструкторы, деструкторы, оператор присваивания и друзья.