【问题标题】:C++ Why parameterised constructor works diffrent with char*? [duplicate]C++ 为什么参数化构造函数与 char* 不同? [复制]
【发布时间】:2021-07-02 01:47:27
【问题描述】:

我最近开始使用 C++ 类,一切都很好,直到我想创建一个带有 'char*' 参数的类。

我创建了一个默认构造函数、一个参数化构造函数、一个复制构造函数和一个析构函数。

在 int* / float 参数上对其进行了测试,并且它有效。

现在我尝试切换到 char* 并且......它没有正确打印我的字符串;

有课:

class parent{

protected:

    char *username;

public:

    parent()
    {
        username=NULL;
    }


    parent(char name[10001])
    {
        int k=strlen(name);
        username = new char[k+1];
        strcpy(username, name);
    }


    parent(const parent &p1)
    {
        int k= strlen(p1.username);
        char *temp = new char[k+1];
        strcpy(temp,p1.username);

        if(username!=NULL)
            delete[] username;
        k=strlen(temp);
        username = new char[k+1];
        strcpy(username, temp);

    }

    void print()
    {
        cout << username << '\n';
    }


    ~parent()
    {
        delete[] username;
    }

};

当我像这样调用构造函数时会出现问题:

char name[10001]="my name";

parent o1;
o1=parent(name);
o1.print();

但是当我这样做时似乎很好:

parent o1(name);

再次,我用 int* / float 参数测试了这个方法,没有问题。 那么为什么 char* 的效果不一样呢?

【问题讨论】:

  • 您没有赋值运算符重载。由于您是动态分配的,因此您也需要这样做,否则您将获得免费的副本。显然o1 = parent(name); 也需要这个。
  • 最重要的是,print 如果没有分配用户名,将会崩溃,你应该在默认构造函数中为它分配一个空字符串,或者你需要验证它不是 nullptr .
  • @Devolus 谢谢伙计,现在似乎很好,虽然它不适用于具有更多 char* 参数的派生类孩子,但我试图弄清楚。
  • “我用int*/float类参数测试了这个方法,没有问题”int* 对应的 strlen(name) 是哪个?

标签: c++ class constructor default-constructor


【解决方案1】:

正如评论中提到的,您应该首先阅读The rule of three

如果一个类需要用户定义的析构函数、用户定义的复制构造函数或用户定义的复制赋值运算符,那么几乎可以肯定这三者都需要。

所以你应该自己定义一个复制赋值运算符。可以这样实现:

parent& operator= (const parent &p1)
{
    parent temp(p1);    // use copy constructor, you already defined

    std::swap(username, temp.username); // just swap our 'invalid' username with username, initialized in temp by copy constructor

    return *this;
    //  a destructor for temp is being called, which handles resourse deallocation
}

附:在 C++11 中引入 move semantic 之后,三的规则已经过时了。现在最好实现移动构造函数和移动赋值运算符,以及其他。

【讨论】:

  • @ZethGaming 要将它与派生类一起使用,您应该重写那些 3/5 方法和构造函数,以处理仅出现在派生类中的数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 1970-01-01
  • 2012-09-15
  • 2020-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多