试图引用已删除的函数 - ostream

时间:2014-08-22 05:22:15

标签: c++ c++11

我正在尝试向我的类添加输出operator <<,但在编译时(VS2013)我有一条消息:

"error C2280:
'std::basic_ostream<char,std::char_traits<char>>::basic_ostream(const
std::basic_ostream<char,std::char_traits<char>> &)' : attempting to
reference a deleted function".

这是我的代码:

#include "Client.h"

Client::Client(MyString id, MyString full_name, char gender, unsigned short age, unsigned short hobbies_num, char** hobbies_list)
{
    this->id = id;
    this->full_name = full_name;
    if (gender == 'm' || gender == 'M')
        this->gender = 'M';
    else if (gender == 'f' || gender == 'F')
        this->gender = 'F';
    else
        cout << "wrong gender value" << endl;
    if (age >= 18)
        this->age = age;
    else
        cout << "wrong age value" << endl;
    this->hobbies_num = hobbies_num;
    this->hobbies_list = hobbies_list;
}

Client::Client(const Client& other)
{
    this->id = other.id;
    this->full_name = other.full_name;
    this->gender = other.gender;
    this->age = other.age;
    this->hobbies_num = other.hobbies_num;
    this->hobbies_list = other.hobbies_list;
}

Client::~Client()
{
    for (int i = 0; i < hobbies_num; i++) // deleting 2 dimension array
        delete[] hobbies_list[i];
    delete[] hobbies_list;
}

Client& Client::operator = (const Client& other)
{
    if (this->id == other.id) //checks if the client is not the same client
        return *this;
    else
    {
        for (int i = 0; i < hobbies_num; i++) // deleting 2 dimension array
            delete[] hobbies_list[i];
        delete[] hobbies_list;
        return Client(other);
    }

}

ostream& operator << (ostream& cout, const Client& for_print)
{
    return cout << for_print.id << endl 
                << for_print.full_name << endl 
                << for_print.gender << endl 
                << for_print.age << endl 
                << for_print.hobbies_num << endl;
}

该消息在返回cout的行上。 这是原型:

#include "MyString.h"
#include <iostream>
#include <stdlib.h>

using namespace std;
class Client
{
    MyString id;
    MyString full_name;
    char gender;
    unsigned short age;
    unsigned short hobbies_num;
    char ** hobbies_list;
public:
    Client(MyString, MyString, char, unsigned short, unsigned short, char**);
    Client(const Client& other);
    ~Client(); //dtor
    Client& operator = (const Client&);  //=
    friend ostream& operator << (ostream&, const Client& for_print);
};

我在网上找不到任何解决方案。同一个命令在同一个解决方案中适用于另一个类。

1 个答案:

答案 0 :(得分:0)

您没有发布编译器错误的确切位置,但我会尝试猜测它。假设您尝试在代码中执行以下操作(我不会尝试使用任何C ++ 11构造可移植):

char *hobbies[] = {
    "hobbie1",
    "hobbie2",
    /* ... */
};
...

Client a("cl1", "joseph", 'm', 20, hobbies, sizeof hobbies/sizeof hobbies[0]); 
/* object declaration with initialization, constructor is called for a */

然后

a = Client("cl2", "john", 'm', 22, hobbies, sizeof hobbies/sizeof hobbies[0]); 
/* assignment statemement, constructor is being called for right expression 
 * and then assignment operator is called to assign it to a.  
 * Equivalent to:
 * a.Client::operator=(Client("cl2",...));
 * a new object is created by the compiler, passed as parameter and destroyed
 * when the call to operator= is finished, before assigning to a. 
 */

在最后一个语句中,编译器尝试构造一个新对象(用于表达式求值)并使用运算符a将其分配给Client::operator=(const Client&other);,并将参数other实例化为此新对象创建对象(编译器只是解除分配它,调用析构函数,当语句完成时,您可以在~Client()正文中检查此放置跟踪代码)。就在您返回Client(other)(在Client :: operator = body的最终return语句中)时,您实例化一个类型Client的新表达式,其值已复制为表达式评估完成后,编译器将删除的内容(创建客户端以将其传递给赋值运算符或为return语句构造的客户端)当返回语句时,它们将不复存在刚执行,所以你不能在操作员调用之外访问它们(我认为这是你从编译器得到的错误)。你最好以这种方式重写Client::operator=(const Client& other)

Client& Client::operator=(const Client& other)
{
    if (this == &other)  /* the same object in both sides */
        return *this;
    else {
        /* delete local memory assignated 
         * **in constructor** to object, not elsewhere
         */
        /* do the actual assignments onto *this, 
         * don't create another instance or value.  This
         * is an assignment operation, you are supposed to
         * change the values of *this
         */

        return *this;  
        /* **never** return a local copy made by the compiler
         * inside the function call, it ceases to exist just
         * on returning from it */
    } /* if */
} /* Client::operator=(const Client&) */

我不相信这个例子在另一个环境中编译好,这是错误的C ++构造。

您还可以看到我如何使用静态char数组(而不是string s)调用构造函数,因此不能在Client的析构函数中释放它们(以说明您最好不要释放它们)析构函数中的内存(如果已在其他地方分配)。