Здравствуйте, blacksun, Вы писали:
B>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
Здравствуйте, blacksun, Вы писали:
B>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
Ну, во-первых, не наследуются функции-члены, автоматически генерируемые компилятором: копирующий оператор присваивания и деструктор; а во-вторых, не наследуются конструкторы, причем, не только автоматически генерируемые — копирующий и по умолчанию — а, наверное, можно сказать, что все.
Здравствуйте, rg45, Вы писали:
R>Ну, во-первых, не наследуются функции-члены, автоматически генерируемые компилятором: копирующий оператор присваивания и деструктор; а во-вторых, не наследуются конструкторы, причем, не только автоматически генерируемые — копирующий и по умолчанию — а, наверное, можно сказать, что все.
Неправда ваша про оператор. Наследуется он на общих основаниях — 13.5/6 "Operator functions are inherited in the same manner as other base class functions"
Если не поможет, будем действовать током... 600 Вольт (C)
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>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
Здравствуйте, blacksun, Вы писали:
B>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
Здравствуйте, wvoquine, Вы писали:
W>Здравствуйте, blacksun, Вы писали:
B>>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
W>Приватные члены, типа, не рассматриваются вообще?
К ним нет доступа, но они скорее наследуются, так как в объектах производного класса присутствуют.
Здравствуйте, 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;
}
Здравствуйте, wvoquine, Вы писали:
B>>Задали вопрос на собеседовании, я до сих пор в сомнениях. Ответил что все наследуется, хотя сейчас сомнительно насчет недефолтовых конструкторов.
W>Приватные члены, типа, не рассматриваются вообще?
Они не доступны, но они наследуются. Для того, чтобы в этом убедиться, достаточно какую-нибудь функцию объявить другом базового класса. Вот пример: http://ideone.com/1Twca
Здравствуйте, rg45, Вы писали:
R>То, что копирующий оператор присваивания базового класса доступен из производного, вовсе не означает, что он наследуется. Ты еще разок внимательно взгляни на приведенный мной пример и ответь на один вопрос: откуда вызвается Aggregated::operator=? (То, что он вызывается очевидно из секции output). Вариант ответа на этот вопрос только один: из сгенерированного компилятором копирующего оператора присваивания: Derived::operator=. А это означает, что производный класс имеет свой сообственный копирующий оператор присваивания, который скрывает копирующий оператор присваивания базового. Скрывает, а не наследует, понимаешь? И, на всякий случай, еще разок сошлюсь на стандарт: п.13.5.3/1.
А твой пример можно переписать вот так: http://ideone.com/mblKt
В этом случае Aggregated::operator= вызван не будет. Т.е. для объекта производного класса мы можем использовать оба оператора. Единственная разница — для оператора производного класса можно использовать синтаксический сахар — запись d1 = d2, вместо d1.operator=(d2), а в остальном принципиальной разницы между ними нет никакой.
Здравствуйте, 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), а в остальном принципиальной разницы между ними нет никакой.
Здравствуйте, 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;
}
Здравствуйте, 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;
}