你看到这个C ++代码有什么问题吗?

时间:2010-11-21 04:41:41

标签: c++

class A
{
public:
    A(){}
    ~A(){}
    void DoSomething(int x){}   
};

void func(int i)
{
    A *pa = new A();
    pa->DoSomething(i);
    delete pa;
}

你们看到这段代码有什么问题吗? 我只能看到以下两点:

  1. func 仅在A类对象上运行,应该成为A的成员
  2. 应该在堆栈而不是堆上创建
  3. 类A的对象。
  4. 还有其他想法吗?

4 个答案:

答案 0 :(得分:9)

  应该在堆栈而不是堆上创建

A的对象。

是的,pa应该创建为自动变量(在堆栈上)而不是动态(在堆上)。

但是,写入也是错误的,因为它不是异常安全的。如果pa->DoSomething(i)抛出异常,您将泄漏pa指向的对象。

管理资源生命周期的正确方法是使用范围限制资源管理(SBRM;也称为资源获取是初始化)。管理动态分配对象的RAII方法是使用智能指针:

void func(int i)
{
    std::auto_ptr<A> pa(new A());
    pa->DoSomething(i);
}

手动资源管理既脆弱又危险,因为它很容易出错。在这个简单的例子中,很容易看出pa->DoSomething(i)没有抛出异常,因为它根本不做任何事情。但在几乎每一个真正的程序中,都不是那么容易。

随着程序规模和复杂性的增加,手动资源管理很快变得非常困难。使用范围限制资源管理进行自动资源管理可以很好地扩展。

  

func仅针对课程A的对象进行操作,并且应该成为A的成员。

这不正确。如果需要访问对象的内部状态,则只应将函数实现为成员函数。这意味着您应该尽可能将函数实现为非成员函数。

您拥有的成员函数越多,彻底测试类所需的工作就越多,因为有更多方法可以修改类的内部状态。

Herb Sutter解释了这一原则,打破了他本周大师文章"Monoliths Unstrung."中的std::string课程。{/ p>

答案 1 :(得分:2)

执行A :: DoSomething()时,func()上发生任何异常都会导致内存泄漏。使用智能指针(例如std :: auto_ptr)

答案 2 :(得分:0)

此外,需要复制构造函数,赋值运算符或析构函数的类通常需要全部三个(我知道,这个是空的 - 只是说)。

答案 3 :(得分:0)

这是真正的代码吗?然后无状态类是完全多余的,void DoSomething(int x)应该是正常的函数。如果没有,请发布真实的代码,否则很难提供进一步的建议。