【问题标题】:Can a class constructor be called from a method? [closed]可以从方法中调用类构造函数吗? [关闭]
【发布时间】:2015-02-14 02:17:33
【问题描述】:

如果我有以下类:

class A {
private:
    int *x;
public:
    A() { x = new int; *(A::x) = 0; }
    A(const int *y) { x = new int; *(A::x) = *y; }
    ~A() { delete x; }
    void operator = (const int *y) { A(y); }
};

int main() {
    A a;
    int y = 3;
    a = &y;

    return 0;
}

我希望赋值语句调用= 方法,然后通过调用相应的构造函数来设置x 成员。但是,赋值后,x 的值似乎仍然是NULL,而y 的值没有赋值。

那么,从方法调用构造函数是定义的操作吗?如果是这样,我的代码中缺少什么?使用调试器,我验证了构造函数实际上被调用,只是一旦流从构造函数返回= 方法,复制的值就不会保留。

【问题讨论】:

  • @dyp 不,它没有。它将创建一个名为 y 的局部变量,类型为 A,而不是临时变量,除非在 C++ 中在函数顶层有一个与函数参数同名的局部变量是错误的。跨度>
  • @dyp - 好的,这是否意味着我不能从方法调用构造函数?
  • void operator = (const int *y) { A(y); } 至少应该是 A& operator = (const int *y) { A(y); return *this; }A(y); 没有意义(实际上是本地函数声明)。
  • @ysap 关于构造函数和调试器,当你中断构造函数时,确保你知道构造函数属于哪个对象。 IE。 (对于visual studio)在“watch”中输入“this”——这将显示你当前对象的地址。您将看到该构造是从您显然期望的不同对象触发的。
  • @JonathanWakely - 原因是“离题”,我看不出如何。无论如何,我在这里问过这个问题:meta.stackoverflow.com/q/280382/274579

标签: c++ class methods constructor


【解决方案1】:

当您像以前一样调用构造函数时,它会被解释为创建类 A 的匿名对象的表达式。该匿名对象在创建它的语句结束时被销毁。所以什么也没有发生。

我建议您进行以下更改:

class A {
private:
    int *x;
public:
    A() { x = new int; *x = 0; }    // No need of A:: 
    A(const int *y) { x = new int; *x = *y; }
    ~A() { delete x; }
    A& operator= (const int *y) { *x=*y; return *this;  } // x was already iniatilized, so we keep it
};

但其实这里不需要指针,所以可以进一步简化:

class A {
private:
    int x;
public:
    A() :x(0) { }  
    A(int y) : x(y) { }
    ~A() { }
    A& operator= (const int y) { x=y; return *this;  } 
};

编辑:

在评论中,您解释说您需要指针,并且您的目的是避免重复代码。然后我建议你另一种选择。

如前所述,您不能调用operator=() 中的构造函数。但是根据标准,您可以做相反的事情(第 12.7/4 节:可以在构造或销毁期间调用成员函数,包括虚函数)。然后,您可以将其与委托构造函数机制结合起来:

A(const int *y) : A() { *this = y; }   // calls default constructor and then uses assignment to do copy. 

但请注意,此处与普通复制构造函数可能存在细微差别,例如,如果您有一些引用成员。

【讨论】:

  • 谢谢。我确实需要指针,因为这只是我实际案例的摘录,我确实使用了指针。您对修复的建议可能会奏效,这就是我最终在我的程序中执行此操作的方式(当然,需要对我的实际情况进行调整)。但是,我想重用构造函数,我已经有类似的代码。
  • @ysap 好的!我进行了编辑,提出了另一种在分配和构造函数之间重用代码的替代方案。
  • 谢谢,是的,我知道另一种可能性。在这种特殊情况下,它看起来不太合适,因为除了y 参数之外,构造函数还包含更多参数,并且我希望= 运算符用于可能的构造选项的一个非常特定的子集中。因此,构造函数中的代码是我最终添加到 = 方法中的代码的超集。
  • 好的!然后您仍然可以选择使用私有成员函数在复制构造函数和赋值之间共享一些公共代码
  • 没错。在这一点上,我对代码重复感到满意。共享代码所需的开销似乎太不值得了。
【解决方案2】:

没有。构造函数用于创建对象,您不能在现有对象上再次调用它们。

对象的生命周期开始一次,生命周期结束(最多)一次。你想要做的就像是两次出生,这听起来很混乱。

【讨论】:

    猜你喜欢
    • 2011-04-08
    • 2017-04-18
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 2016-05-31
    • 2010-10-18
    • 1970-01-01
    • 2011-07-10
    相关资源
    最近更新 更多