C ++如何在类函数内构造一个对象,做一些操作并返回值?

时间:2014-04-02 21:58:27

标签: c++ destructor

我不打算通过整个源代码,因为它是1000多行,但我特意为我感兴趣的事情构建了一个类似的案例。注意这个源代码:

#include <iostream>
using namespace std;

class Person
{
public:
    Person();
    Person(char*);
    ~Person();
    Person& operator=(const Person&);
    friend Person& example(const Person&);
    void print() const;
private:
    char* name;
};

Person::Person()
{
    name = new char[12];
    name = "Temp";
}

Person::~Person()
{
     delete[] name;
}

Person::Person(char* _name)
{
    name = new char[strlen(_name)+1];
    strcpy_s(name,strlen(_name)+1,_name);
}

Person& example()
{
    char* TestName = new char[11];
    TestName = "ShouldStay";
    Person B(TestName);
    return B;
}

void Person::print() const
{
    cout << name;
}

int main()
{
    example();
    return 0;
}

在这种情况下,example()函数将返回:

  • 示例返回{名称= 0x007cad88“îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþ...}人&安培;

显然,在返回命令中调用析构函数并删除堆中的内存(因此我无法对指针做任何进一步操作 - 它指向已释放的内存 - 没有数据)。

我的问题是 - 如何避免这种行为?避免此类问题最优雅的方法是什么?

提前谢谢!

3 个答案:

答案 0 :(得分:1)

  1. 使用string而不是char[]来避免使用new
  2. 返回Person而不是Person&,作为本地范围的类 他们离开范围后被摧毁。虽然这会导致一个 根据编译器设置进行复制。这当然取决于提供适当的拷贝构造函数。
  3. 为确保避免复制,请将example的签名更改为:

    void example(Person& person)
    

    并填写函数内输入人员的字段。 Person的范围将绑定到调用范围(或者您构造它的任何其他位置)。这种方法有缺点,例如你不能将结果链接在一起。

答案 1 :(得分:1)

您的代码包含许多逻辑错误:

Person::Person()
{
    name = new char[12];
    name = "Temp";
}

在上面的函数中,你分配一个包含12个元素的char数组,然后你就会忘记它,而是让name指向一个字符串文字。

Person::~Person()
{
     delete[] name;
}

whoopps。如果Person是从默认构造函数构建的,那么这将delete一个字符串文字。 C ++中的禁忌。

Person::Person(char* _name)
{
    name = new char[strlen(_name)+1];
    strcpy_s(name,strlen(_name)+1,_name);
}

不是100%确定strcpy_s是什么,但本例中的代码分配了一个数组,似乎将字符串复制到数组中。这似乎没问题(但由于很多原因,strcpy(name, _name);只会更好。)

Person& example()
{
    char* TestName = new char[11];
    TestName = "ShouldStay";
    Person B(TestName);
    return B;
}

此代码严重破坏。首先,它通过引用返回一个临时对象。一个非常糟糕的主意。它还分配了一个数组,并再一次忘记它并使用字符串文字。

让代码工作的最优雅方式(实际上是我认为唯一的方法)是首先了解C ++的基础知识是如何工作的。你应该先开始by reading a good C++ book from cover to cover,然后才能开始用C ++编写代码。

你的1000行源代码很可能只是垃圾。我不是说你是愚蠢的,只是因为你不了解C ++的基础知识。首先通过阅读来照顾​​它们,而不是试验编译器。

您无法通过实验来学习C ++有两个原因:

  • 由于它的历史,这是一个复杂的,有时甚至是完全不合逻辑的语言。猜测几乎总是一个糟糕的举动。无论你多么聪明,你都无法正确猜出委员会的决定。

  • 当你犯了一个错误时,天使没有运行时错误告诉你。很多时候,显然程序仍然有效......直到它由你的老师,老板或配偶经营。通过编写代码和观察发生的事情来猜测C ++规则是无稽之谈。

答案 2 :(得分:0)

Person& example()
{
    char* TestName = new char[11];
    TestName = "ShouldStay";
    Person B(TestName);
    return B;
}

上面在堆栈上创建了一个Person实例,作用于该函数。因此,当函数返回时,将调用Person的析构函数,并返回对已销毁对象(在堆栈上)的引用。

此外,您应该考虑返回Person的副本,或者您需要使用new运算符在堆上创建person实例并返回指向该实例的指针。