Насколько мне известно, результат выполнения 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 "<
";
}
A::~A()
{
std::cout<<"A "<
";
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
Комментариев нет:
Отправить комментарий