你能在C ++中显式调用实例化对象的类构造函数吗?

时间:2008-11-24 11:01:32

标签: c++ constructor

创建类的实例后,我们可以显式调用构造函数吗? 例如

class A{
    A(int a)
    {
    }
}

A instance;

instance.A(2);

我们可以这样做吗?

7 个答案:

答案 0 :(得分:14)

您可以使用允许

的新地址http://en.wikipedia.org/wiki/Placement_new
new (&instance) A(2);

但是,从您的示例中,您将在对象上调用两次构造函数,这是非常糟糕的做法。相反,我建议你只做

A instance(2);

Placement new通常仅在您需要预分配内存时使用,例如在自定义内存管理器中。

答案 1 :(得分:10)

没有。

为集合创建一个方法并从构造函数中调用它。此方法也将在稍后提供。

class A{
    A(int a) { Set(a); }
    void Set(int a) { }
}

A instance;

instance.Set(2);

您可能还需要默认值或默认构造函数。

答案 2 :(得分:4)

没有

Calling instance.A() or A(1) is seens as casting  'function-style cast' : illegal as right side of '.' operator

通常,如果在构造函数中需要函数/功能,并且在构造对象之后,它将被放置在init()方法中并在构造函数和其他地方使用。

示例:

 class A{
      A(int a)
       { 
        init(a);
       }

     void init(int a) { } 
     }

        A instance;

        instance.init(2);

答案 3 :(得分:3)

我很确定你做不到。 这就是重点,构造函数是创建类的一个实例。

如果根本没有调用构造函数,或者被调用两次 - 它会产生什么后果呢?

当然,你可以做的是将一些构造函数逻辑提取到方法中,并在构造函数和创建对象之后调用该方法。

答案 4 :(得分:1)

顺便说一句,这听起来像是一个设计缺陷。构建对象后,永远不需要重新构造它。这种变量名重用使代码更难理解。出于这个原因,通过额外的函数initset提供类似构造函数的功能通常是错误的(但有时是不可避免的)。

正如Michael所说,可以在这里使用placement new,但它确实用于不同的用途。此外,在内存位置构造新对象之前,必须显式销毁旧对象:

instance.~A();

此外,placement new会对您的内存产生负面影响,因为重载可能会导致它传递的内存属于堆!总之:。做。此

编辑要证明调用析构函数 非常必要(对于非POD),请考虑以下示例代码:

#include <iostream>

struct A {
    A(int a) { std::cerr << "cons " << a << std::endl; }
    ~A() { std::cerr << "dest" << std::endl; }
};

int main() {
    A instance(2);
    new (&instance) A(3);
}

正如预期的那样,该程序产生以下输出:

cons 2
cons 3
dest

...这意味着第一个对象的析构函数被调用。对A可能获得的任何资源也是如此。

答案 5 :(得分:0)

不,你不能那样做。调用构造函数的唯一方法是使用关键字“new”。

答案 6 :(得分:-1)

总结一下,指定显式构造函数的三种方法是通过

  1. 一个实例(2); // A实例= 2;曾经工作过吗?

  2. A * instance = new A(2); //永远不要确定&amp;与*在这里,我自己

  3. new(&amp; instance)A(2);

  4. 和那些的味道。 idea 的目标是安排在任何时候构造的对象都没有处于正确的初始化状态,并且构造函数旨在确保这一点。 (这意味着方法不必检查是否已成功调用某个.init(...)方法。)

    这让我觉得这是一个更具功能性的方法,特别是对于作为框架的一部分并在库中重用的类。如果这是你感兴趣的,那么努力让所有构造函数(包括任何默认构造函数)都提供一个完整的实例。

    异常情况:如果构造函数可能失败,那么构造函数操作中可能没有这些东西,除非从构造函数中抛出异常是合适的。有些人喜欢使用后续方法传播的“空白”实例,甚至是暴露给初始化成员。有趣的是探索减轻这种情况的方法,并且拥有强大的实例,这些实例没有需要在方法实现和使用中受到保护的错误状态。

    PS:在某些复杂的情况下,将初始化实例(引用)作为函数或“工厂”类上的方法的结果传递可能是有用的,以便中间的,设置不足的实例从来没有在封装工厂类实例或函数之外看到过。这给了我们,

    4。 A * instance = MakeAnA(2);

    5。 A * instance = InterestingClass.A(2);