Страницы

Поиск по вопросам

вторник, 20 ноября 2018 г.

Возможно ли присвоить результат new не указателю?

Насколько мне известно, результат выполнения new нужно присваивать указателю, т.е.:
T t = new T(); //должна быть ошибка. Несоответствие типов т.к. new возвращает указатель T *t = new T(); // Правильный вариант
Однако, необъяснимым для меня образом, следующий код делает первый вариант возможным. Причем только для одного конечного класса C1. Если попытаться сделать подобное с другим C2, появляется ошибка. Причем если упростить конструктор (убрать список инициализации и аргументы), то все будет работать по-обычному.
#include
class A { private: int id; static int instrumentsCount; static int lastId; public: A(); virtual ~A() = 0; }; class B:public A { private: int field1; public: B(int arg):A(),field1(arg) {std::cout<<"B
";} }; class C1:public B { private: const bool field2; public: C1(bool o = true):B(170),field2(o){std::cout<<"C1
";} ~C1(); }; class C2:public B { private: const int field3; public: C2(int d = 20):B(120),field3(d){std::cout<<"C2
";} ~C2(); }; int A::instrumentsCount = 0; int A::lastId = 0; A::A() { this->id = A::lastId++; A::instrumentsCount++; std::cout<<"A "<id<<" created
"; } A::~A() { std::cout<<"A "<id<<" destroyed
"; A::instrumentsCount--; } C1::~C1(){} C2::~C2(){}
int main(int argc, char *argv[]) { C1 c1 = new C1(true); C2 *c2 = new C2(10); return 0; }
Как результат выводится следующее:
A 0 created B C1 A 1 created B C1 A 2 created B C2 A 1 destroyed
Что в принципе логично, но почему конструктор базового класса A вызывается при создании C1 два раза? Прошу открыть мне глаза на мои ошибки( Использую QT Creator 5.9


Ответ

Имеется фундаментальный тип, для которого вы можете написать выражение
T t = new T();
Таким типом является фундаментальный тип bool.
bool b = new bool();
Если инициализатор отличен от нуля, то переменная получает значение true , в противном случае значение false
Из стандарта C++ (4.14 Boolean conversions)
1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (8.6), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.
Однако такой код ведет к утечке памяти, так как значение указателя на выделенную память теряется.
В примере кода из вашего вопроса в классе C1 имеется конструктор преобразования
C1(bool o = true):B(170),field2(o){std::cout<<"C1
";}
Параметр этого класса имеет тип bool, а переданный в качестве аргумента указатель может неявно быть преобразован в тип bool

Комментариев нет:

Отправить комментарий