搜尋

首頁  >  問答  >  主體

c++11 - 这段 C++ 代码究竟创建了多少个对象?

class stu{
public:
    int age;
    int score;
    stu() = default;
    stu(int a, int s):
        age(a), score(s) { cout << " i am constructor" << endl;}
    stu(const stu& stu1):
        age(stu1.age), score(stu1.score) { cout << " i am copy constructor" << endl;}
};
const stu combine(const stu &stu1, const stu &stu2)
{
    stu new_stu(stu1.age + stu2.age, stu1.score + stu2.score);
    return  new_stu;
}
int main()
{
    stu stu1(22,100);
    stu stu2(23,99);
    stu result(combine(stu1, stu2));
    cout << result.age << result.score << endl;
}

我的理解是应该创建了四个对象,其中一个是临时对象,由combine(stu1, stu2)函数返回时创建。类的构造函数执行打印一行字符串的功能,通过有多少行字符串可以推出执行了多少次构造函数,代码在运行时只有三行字符串,意味着只创建了三个对象,究竟哪里有问题??

巴扎黑巴扎黑2767 天前881

全部回覆(3)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:07:32

    1. 先修正一點, 臨時物件由combine傳回是沒有錯的, 但是這裡呼叫的是拷貝建構函數,而非建構函式.然後result宣告的時候又呼叫了一次建構函數,所以最終的次數是兩次建構子+一次拷貝建構子+一次建構子

    2. 那疑問來了, 為啥這裡面的拷貝構造函數完全沒有體現呢, 這是因為編譯器會略過這次拷貝構造函數而直接執行構造函數, 所以結果就變成了三次建構函數,相關內容可以參考c++ primer十三章.

    雖然編譯器會跳過了拷貝建構函數, 不過要確保類別的拷貝建構函數可以存取的(非private), 可以這麼驗證會報錯.

    class stu{
    public:
        int age;
        int score;
        stu() = default;
        stu(int a, int s):
            age(a), score(s) { cout << " i am constructor" << endl;}
    prvate:
        //虽然编译器绕过了拷贝构造函数,但是仍然需要拷贝构造函数可见.这里会编译错误
        stu(const stu& stu1):
            age(stu1.age), score(stu1.score) { cout << " i am copy constructor" << endl;}
    };

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 13:07:32

    這是RVO(Return Value Optimization)

    參考:https://en.wikipedia.org/wiki/Return_value_optimization

    回覆
    0
  • 迷茫

    迷茫2017-04-17 13:07:32

    產生了五個物件
    stu1 +1
    stu2 +1
    new_stu +1
    const stu +1
    result +1

    編譯器預設會開啟回傳值最佳化
    在用gcc編譯時加上 -fno-elide-constructors選項就可以關掉此最佳化。
    執行編譯後的程式的結果如下:
    i am constructor
    i am constructor
    i am constructor
    i am copy constructor
    i am copy conoror
    45199<% >

    回覆
    0
  • 取消回覆