C++;vs Java构造函数

C++;vs Java构造函数,java,c++,inheritance,programming-languages,Java,C++,Inheritance,Programming Languages,根据John C.Mitchell-编程语言中的概念 […]Java保证 每当 对象被创建。[……] 这是一个java特性,使C++在行为上与C++不同。所以我必须指出,C++在某些情况下不为类创建任何构造函数,即使创建了该类的对象。 void * operator new ( size_t size ) { void *p = malloc(size); if(p) return p; else cout<<endl

根据John C.Mitchell-编程语言中的概念

[…]Java保证 每当 对象被创建。[……]

这是一个java特性,使C++在行为上与C++不同。所以我必须指出,C++在某些情况下不为类创建任何构造函数,即使创建了该类的对象。

void * operator new ( size_t size )
{

     void *p = malloc(size);

     if(p)
       return p; 
     else
        cout<<endl<<"mem alloc failed";
}

class X
{   

   int X;

};

int main()
{

       X *pX;

       pX = reinterpret_cast<X *>(operator new(sizeof(X)*5)); // no ctor called

}
我认为当继承发生时会发生这种情况,但我无法为这种情况找到一个例子


C++中,当一个对象被实例化时,必须调用该类的构造函数。

java构造函数可以调用同一个类的另一个构造函数。在C++中,这是不可能的。p> POD(普通的旧数据类型)不是通过C++中的构造函数初始化的:

struct SimpleClass {
    int m_nNumber;
    double m_fAnother;
};

SimpleClass simpleobj = { 0 }; 
SimpleClass simpleobj2 = { 1, 0.5 }; 
在这两种情况下,都不会调用构造函数,甚至不会调用生成的默认构造函数:

  • 未使用初始值设定项声明的非常量POD对象具有“不确定的初始值”
  • POD对象的默认初始化为零初始化。 ()

然而,如果SimpleClass本身定义了一个构造函数,SimpleClass将不再是一个POD,并且将始终调用其中一个构造函数。

只有当您重载新的运算符函数时,才不会调用构造函数(它用于避免调用构造函数),否则在标准中,在创建对象时调用构造函数

void * operator new ( size_t size )
{

     void *p = malloc(size);

     if(p)
       return p; 
     else
        cout<<endl<<"mem alloc failed";
}

class X
{   

   int X;

};

int main()
{

       X *pX;

       pX = reinterpret_cast<X *>(operator new(sizeof(X)*5)); // no ctor called

}
void*运算符新建(大小)
{
void*p=malloc(尺寸);
如果(p)
返回p;
其他的

cout他的意思是在Java中,总是调用超类的构造函数。这是通过调用super(…)来完成的,如果省略此编译器,它将为您插入一个。唯一的例外是一个构造函数调用另一个构造函数。在这种情况下,其他构造函数应该调用super(…)

编译器的这种自动代码插入实际上很奇怪。如果您没有super(…)调用,并且父类没有不带参数的构造函数,则会导致编译错误。(对于自动插入的内容,有编译错误是很奇怪的。)


C++不会自动插入。

C++中有一些特殊的情况,其中不调用构造函数。特别是对于POD类型,在某些情况下,隐式定义的默认构造函数将不被调用。
struct X {
   int x;
};
int main() {
   X x;        // implicit default constructor not called
               //    No guarantee in the value of x.x
   X x1 = X(); // creates a temporary, calls its default constructor
               //    and copies that into x1. x1.x is guaranteed to be 0
}
我不太记得可能发生这种情况的全部情况,但我似乎记得大部分情况都是在这种情况下发生的

为进一步解决这一问题:

这是一个java特性,它使C++在行为上与C++不同。因此我必须指出C++在某些情况下不为类创建任何构造函数,即使该类的对象被创建。

void * operator new ( size_t size )
{

     void *p = malloc(size);

     if(p)
       return p; 
     else
        cout<<endl<<"mem alloc failed";
}

class X
{   

   int X;

};

int main()
{

       X *pX;

       pX = reinterpret_cast<X *>(operator new(sizeof(X)*5)); // no ctor called

}
是的,对于POD类型,您可以实例化对象,并且不会调用构造函数

当然,这样做是为了与C兼容

(正如尼尔评论的那样)

我认为当继承发生时会发生这种情况,但我无法为这种情况找到一个例子


这与继承无关,但与实例化对象的类型有关。对于声明构造函数的C++类型,

,不使用构造函数就不可能创建这些类型的实例。例如:

class A {
   public:
      A( int x ) : n( x ) {}
  private:
      int n;
};

如果不使用A(int)构造函数,就无法创建A的instancev,除非通过复制,在本例中,复制将使用合成的复制构造函数。在这两种情况下,都必须使用构造函数。

据我所知,Meyers在他的“有效的C++”中表示仅当控制流到达其构造函数的末尾时才创建该对象。否则,它不是对象。每当您想要为实际对象滥用一些原始内存时,可以执行以下操作:

class SomeClass
{
   int Foo, int Bar;
};

SomeClass* createButNotConstruct()
{
   char * ptrMem = new char[ sizeof(SomeClass) ];
   return reinterpret_cast<SomeClass*>(ptrMem);
}
class-SomeClass
{
int Foo,int Bar;
};
SomeClass*CreateButnotConstruction()
{
char*ptrMem=新字符[sizeof(SomeClass)];
返回重新解释(ptrMem);
}

你不会在这里碰到任何构造函数,但你可能会认为,你正在操作一个新创建的对象(并且调试时间很长);

试图把C++弄清楚。很多不精确的答案。 在C++中,一个POD和一个类的行为是相同的。总是调用构造函数。对于POD,默认构造函数不做任何事情:它不初始化值。但是,不调用构造函数是错误的。 即使使用继承,也会调用构造函数

class A {
  public: A() {}
};

class B: public A {
  public: B() {}   // Even if not explicitely stated, class A constructor WILL be called!
};

如果您的类定义了至少一个构造函数,那么该语言将不允许您在不调用构造函数的情况下构造该类型的对象

如果您的类没有定义构造函数,那么一般规则是将调用编译器生成的默认构造函数

正如其他海报所提到的,如果您的类是POD类型,那么在某些情况下您的对象将保持未初始化状态。但这并不是因为编译器“没有调用构造函数”。这是因为该类型没有构造函数(或者它有一个什么都不做的构造函数),并进行了一些特殊的处理。但是,同样,POD类型在Java中不存在,因此无法真正进行比较

您还可以绕过一些东西,这样就不会调用构造函数。例如,分配一个缓冲区
char
,获取指向第一个char的指针并将其转换为对象类型。当然,在大多数情况下,未定义的行为是不允许的,但编译器通常不会抱怨


但是,任何一个不明确地说出他们所指的具体拐角情况的书,很可能是垃圾。那么,大多数写C++的人实际上对该语言不太了解,所以这不应该是意外。

< P>有两个java的例子。(我再也不知道了)一个类“可以在没有ca构造函数的情况下构造”