链接类构造函数时的范围问题

时间:2013-05-11 17:47:30

标签: c++ class constructor scope

为什么在链接构造函数时以下内容不起作用:

#include <iostream>
#include <vector>

class cls {
public:
    cls()           {cls(5);}       // want to resize v to 5
    cls(int n)      {v.resize(n);}
    std::vector<int> v;
};

int main(int argc, const char* argv[]) {
    cls x, y(5);
    std::cout << x.v.size() << std::endl;   // prints 0 <- expected 5
    std::cout << y.v.size();                // prints 5
    return 0;
}

演示:http://ideone.com/30UBzS

我希望两个对象都有一个大小为5的v。出了什么问题?

我想这样做的原因是因为编写单独的cls()cls(n) ctors会复制很多代码。

4 个答案:

答案 0 :(得分:2)

cls(5);构造函数内部调用cls::cls()并没有按照您的想法进行操作。它使用第二个cls构造函数创建一个临时变量,该构造函数在;处被销毁。

您可以使用C ++ 11的委托构造函数来实现您的目标:

cls() : cls(5) { }

如果您没有支持C ++ 11的编译器,您可以将公共初始化拉出到另一个函数中,并让两个构造函数都调用:

class cls {
public:
    cls()           { init(5); }
    cls(int n)      { init(n); }
    std::vector<int> v;
private:
    void init(int n) { v.resize(n); }
};

答案 1 :(得分:0)

你应该改变

cls()  {cls(5);} 

cls()  {v.resize(5);} 

否则,您将在构造函数中创建新的临时cls并忽略它。


或者如果你想要delegate the constructor(C ++ 11)就像这样做

cls() : cls(5)  {} 
//   ^^   ^
//        | use cls(int n)

委托构造函数只允许在构造函数的member initialization列表中使用。

答案 2 :(得分:0)

以下是您的需求:

class cls
{
public:
       cls()
       :
       v( 5 ){}               // create v that contains 5 elements ( each initialized to 0 ) - note: this is NOT resizing

        explicit cls( const int size )
        :
        v( size ){}
private:       
        std::vector<int> v;
};

当然,如果您需要在活动对象上调整大小功能,则需要在此主题中提及的“调整大小”方法。

答案 3 :(得分:0)

cal(5)创建一个完全不同的对象,实际上它是一个临时意义,该对象将在其封装表达式的末尾被销毁。或者由于编译器优化,它可能根本不会被调用。

但除此之外,构造函数调用只影响临时而不是调用构造函数的原始对象。

如果你打算缩短代码,你应该创建一个成员函数来执行此操作(假设你的编译器不支持C ++ 11,在这种情况下你可以简单地使用 {{3} } 功能):

class cls
{
    void resize(int n)
    {
        v.resize(n);
    }

    public:
        cls()           { resize(5); }
        cls(int n)      { resize(n); }
        std::vector<int> v;
};