Heim  >  Fragen und Antworten  >  Hauptteil

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 Tage vor574

Antworte allen(4)Ich werde antworten

  • 巴扎黑

    巴扎黑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++不仅要保证没有错误,最好还要消除所有的告警。

    Antwort
    0
  • ringa_lee

    ringa_lee2017-04-17 13:54:45

    拿一个const char* 来初始化 char* 在C++11及以后也是不推荐的,编译器会报warning。你把第一个构造函数+const就好了

    Antwort
    0
  • 怪我咯

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

    关键是 Test y = “haha” 这行代码

    Antwort
    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.

    Antwort
    0
  • StornierenAntwort