Здравствуйте, Bork, Вы писали:
_>И? А причем здесь то как генерируеться неявный конструктор?
B>так в твоем то примере он как раз и не генерируется, а определяется тобой
Здравствуйте, sergey_shandar, Вы писали:
_>Здравствуйте, Bork, Вы писали:
_>>И? А причем здесь то как генерируеться неявный конструктор?
B>>так в твоем то примере он как раз и не генерируется, а определяется тобой
_>Где?
ну собственно вот с чего я начал:
твой код ... _>struct C; _>struct B _>{ _> B() {} _> B(const B &) { std::cout << "copy constructor" << std::endl; } _> B(const C &) { std::cout << "[cencored] constructor" << std::endl; } _>};
_>struct C: B {};
_>Вывод VC 7.1, IMHO, неправильно, бред какой то: _>[cencored] constructor
_>Программа: _>int main() _>{ _> C c; _> C c1 = c; _> return 0; _>}
т.е. вопрос — бред или не бред ?
поразмыслив и поэкспериментировав я получил след. вывод:
логика работы компилятора такая:
если (не определен конструктор копирования ?)
генерируем и выполняем его
иначе { // т.е. определен
выбираем чего вызвать на исполнение
и вот тут то компилятор обнаруживает 2 функции
B(const B &) и B(const C &)
а на входе то С, значит первая функция вызывается с приведением типа,
а вторая без него. следовательно вызывается B(const C &)
}
правильно это или нет, судить не буду, но вполне логично
Здравствуйте, Bork, Вы писали:
_>>>И? А причем здесь то как генерируеться неявный конструктор?
B>>>так в твоем то примере он как раз и не генерируется, а определяется тобой
_>>Где?
B>ну собственно вот с чего я начал:
B>твой код ...
мой...
...
struct C: B {};
...
Не вижу у класса C явного (user-defined) конструктора копирования.
B>поразмыслив и поэкспериментировав я получил след. вывод: B>логика работы компилятора такая:
B>если (не определен конструктор копирования ?) B> генерируем и выполняем его B>иначе { // т.е. определен B> выбираем чего вызвать на исполнение B> и вот тут то компилятор обнаруживает 2 функции B> B(const B &) и B(const C &)
См. стандарт, компилятор ищет только конструктор копирования. Все остальное фантазии, это в отдельный топик.
. Если ты считаешь это настоящим кодом, то видимо спорить вообще безсмысленно...
хехе процитировав реальную программу ты ссылаешься на предыдущие сообщения ...
тут я тебя не понял, т.к. логика слишком запутана
B>>1. вызов конструктора класса А, с передачей ему объекта с1. B>>класс A не знает как преобразовать класс С в класс В, но знает как превратиь С в А поэтому генерируется конструктор по умолчанию A(operator А(С)), который и вызывается.
D>Почему это класс А не знает как преобразовать С в B? Отлично знает это точно такое же преобразование производный -> базовый как C -> A.
а с чего класс А должен что то знать о классе В, у тебя то множественое наследование и классы А и В полностью независимы и ничего не знают о существовании друг друга
B>>2. вызов конструктора класса B, с передачей ему объекта с1. B>>здесь происходит тоже самое что и в п.1
B>>3. вызов конструктора С(С).
D>Какого конструктора С? Это и так конструктор С, один конструктор вызывает другой конструктор того же класса???
имеется ввиду исполнение непосредственного кода функции С(С).
D>Это как раз правильно! В сгенерированной компилятором конструкторе копирования, могут вызываться только конструкторы копирования.
ключевая фраза "В сгенерированной компилятором конструкторе копирования" а ты попробуй их определить и сразу видна разница, т.к. ты считаешься априори умнее компилятора и знаешь что делаешь вот только компилятору тогда по барабану что ты там наопределял и если есть из чего выбирать он будет выбирать на основании правил неявного приведения типа. и в ситуации
class B;
class A
{
A(const A&) {}
A(const B&) {}
};
class B : A {};
void main()
{
B b1;
B b2(b1);
}
конструктор копирования A(const A&) не вызовется никогда, т.к. выбор в пользу A(const B&) предпочтительнее.
Здравствуйте, sergey_shandar, Вы писали:
_>Не вижу у класса C явного (user-defined) конструктора копирования.
а причем здесь класс С ? с ним то как раз проблем нету
или ты считаешь, что если у С нет явно определенного конструктора копирования, то компилятор и в В должен его сам определять ?
B>>поразмыслив и поэкспериментировав я получил след. вывод: B>>логика работы компилятора такая:
_>См. стандарт, компилятор ищет только конструктор копирования. Все остальное фантазии, это в отдельный топик.
а компилятор и ищет и успешно его находит
вот только исполнять он его не будет, если найдет сигнатуру получше
т.к. считает тебя умнее себя, и раз ты выделил наряду с
B(const B&)
еще и
B(const С&)
то ты знаешь что делаешь
Здравствуйте, Bork, Вы писали:
B>Здравствуйте, sergey_shandar, Вы писали:
_>>Не вижу у класса C явного (user-defined) конструктора копирования.
B>а причем здесь класс С ? с ним то как раз проблем нету B>или ты считаешь, что если у С нет явно определенного конструктора копирования, то компилятор и в В должен его сам определять ?
Есть люди которые бояться признавать свои ошибки. Пока.
Здравствуйте, sergey_shandar, Вы писали:
_>Есть люди которые бояться признавать свои ошибки. Пока.
это ты о себе ?
уперевшись в п.12.8.8 не видишь ничего рядом ? но ведь стандарт состоит не только из этого пункта, а еще и существуют различные щекотливые моменты, типа твоего примера, где не все так однозначно и есть поле для размышлений MS решило его по своему, GCC другим способом. Вот только классифицировать это багом я бы не решился
Здравствуйте, sergey_shandar, Вы писали:
_>Есть люди которые бояться признавать свои ошибки.
Ну вообще-то это ошибка microsoft. ^_^
Спасибо, добавил в свою коллекцию багов (да, я энтомолог)
//should print A, but MSVC7.1 print B#include <iostream>
class B;
class A
{
public:
A(){}
A(const A&) { std::cout <<"A"; }
private:
A(const B&) { std::cout <<"B"; }
};
class B : A
{
};
void main()
{
B b1;
B b2(b1);
}
Попробовал скомпилировать IC++ c ключом /Qms1 и /Qms2(Instructs the compiler to enable most Microsoft compatibility bugs./ Instructs the compiler to implement full Microsoft compatibility.), печатает всегда А.
А MSVC — B.
Правильно работающая программа — просто частный случай Undefined Behavior