Question:
As far as I know, the result of executing new must be assigned to a pointer, i.e.:
T t = new T(); //должна быть ошибка. Несоответствие типов т.к. new возвращает указатель
T *t = new T(); // Правильный вариант
However, in an inexplicable way to me, the following code makes the first option possible. And only for one finite class C1. If you try to do this with another C2, an error appears. Moreover, if we simplify the constructor (remove the initialization list and arguments), then everything will work as usual.
#include <iostream>
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\n";}
};
class C1:public B
{
private:
const bool field2;
public:
C1(bool o = true):B(170),field2(o){std::cout<<"C1\n";}
~C1();
};
class C2:public B
{
private:
const int field3;
public:
C2(int d = 20):B(120),field3(d){std::cout<<"C2\n";}
~C2();
};
int A::instrumentsCount = 0;
int A::lastId = 0;
A::A()
{
this->id = A::lastId++;
A::instrumentsCount++;
std::cout<<"A "<<this->id<<" created\n";
}
A::~A()
{
std::cout<<"A "<<this->id<<" destroyed\n";
A::instrumentsCount--;
}
C1::~C1(){}
C2::~C2(){}
int main(int argc, char *argv[])
{
C1 c1 = new C1(true);
C2 *c2 = new C2(10);
return 0;
}
As a result, the following is displayed:
A 0 created
B
C1
A 1 created
B
C1
A 2 created
B
C2
A 1 destroyed
Which is logical in principle, but why is the base class constructor A called twice when C1 is created? Please open my eyes to my mistakes ( I use QT Creator 5.9
Answer:
There is a fundamental type for which you can write an expression
T t = new T();
The fundamental type bool
is such a type.
bool b = new bool();
If the initializer is nonzero, then the variable is set to true
, otherwise it is set to false
.
From the C++ standard (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.
However, such code leads to a memory leak, since the value of the pointer to the allocated memory is lost.
In the example code from your question, class C1
has a conversion constructor
C1(bool o = true):B(170),field2(o){std::cout<<"C1\n";}
The parameter of this class is of type bool
, and the pointer passed as an argument can be implicitly converted to type bool
.