首頁  >  問答  >  主體

C++中constructor的问题

  1. 最近开始学习c++, 自己写了点小代码, 碰到一个问题现在还解决不了.

Test.h

#ifndef GEEK_TEST_H
#define GEEK_TEST_H

#include <cstring>

class Test{
public:
    Test(char* ptr){
        printf("aaaa");
        if(ptr){
            this->ptr = new char[strlen(ptr) + 1];
            strcpy(this->ptr, ptr);
        } else{
            this->ptr = new char[1];
            ptr[0] = '\0';
        }
    }

    Test(const Test& test){
        printf("bbb");
        this->ptr = test.ptr;
    }

    char* ptr;
};

#endif //GEEK_TEST_H

main.cpp

#include <iostream>
#include "Test.h"

using namespace std;

int main() {
    Test y = "haha";
    return 0;
}

这样编译运行是正常的, 但是当我去掉Test.h中第二个构造函数参数列表中的const之后, 就报错了... 也就是把第二个构造函数改成这样 :

    Test(Test& test){
        printf("bbb");
        this->ptr = test.ptr;
    }

报错也奇怪 :

/Applications/CLion.app/Contents/bin/cmake/bin/cmake --build /Users/zhangzhimin/Library/Caches/CLion2016.1/cmake/generated/geek-ef0ba4bc/ef0ba4bc/Debug --target geek -- -j 8
Scanning dependencies of target geek
[ 50%] Building CXX object CMakeFiles/geek.dir/main.cpp.o
/Users/zhangzhimin/ClionProjects/geek/main.cpp:7:14: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
    Test y = "haha";
             ^
/Users/zhangzhimin/ClionProjects/geek/main.cpp:7:10: error: no viable constructor copying variable of type 'Test'
    Test y = "haha";
         ^   ~~~~~~
/Users/zhangzhimin/ClionProjects/geek/Test.h:20:5: note: candidate constructor not viable: expects an l-value for 1st argument
    Test( Test& test){
    ^
1 warning and 1 error generated.
make[3]: *** [CMakeFiles/geek.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/geek.dir/all] Error 2
make[1]: *** [CMakeFiles/geek.dir/rule] Error 2
make: *** [geek] Error 2

希望有大神帮忙解决...

巴扎黑巴扎黑2764 天前573

全部回覆(4)我來回復

  • 巴扎黑

    巴扎黑2017-04-17 13:54:45

    Test y = "haha";

    1. 這條語句,編譯器先用 Test(char ptr) 隱式的 字串轉換為 Test 暫存物件。這個臨時轉換的物件是一個右值,不能有潛在的修改。 把一個const char 型 傳給 char* ,產生了第一個警告。
      2.接著嚐式找一個 拷貝建構函數 將這個臨時物件物件賦給 y, 編譯器只找到了 Test(Test& test), 這裡沒有 const 修飾, 編譯器拒絕傳遞,報了第二個錯誤。第三個提示補充說明 選取的 拷貝建構函數 是 Test(Test& test)。

    C++ 最頭痛的就是複雜性,各編譯器對規範的解釋或寬嚴不一致,因些使用C++不僅要保證沒有錯誤,最好還要消除所有的告警。

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 13:54:45

    拿一個const char* 來初始化 char* 在C++11及以後也是不建議的,編譯器會報warning。你把第一個構造函數+const就好了

    回覆
    0
  • 怪我咯

    怪我咯2017-04-17 13:54:45

    關鍵是 Test y = “haha” 這行程式碼

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-17 13:54:45

    朋友提醒我可能是編譯器的原因, 用vs2015試了下, 瞬間爆炸直接通過(之前用的是mac的終端)... 朋友們怎麼看, 同時剛看了下c++的文檔, 裡面說拷貝構造函數, 可以是const的, 也可以不是.

    ISO C++03:
    12.8
    2 A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&,
    volatile X& or const volatile X&, and either there are no other parameters or else all other
    parameters have default arguments (8.3.6).106) [Example: X::X(const X&) and X::X(X&, int=1)
    are copy constructors.

    回覆
    0
  • 取消回覆