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

Raj*_*pal 0 c++

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

void func(int i)
{
    A *pa = new A();
    pa->DoSomething(i);
    delete pa;
}
Run Code Online (Sandbox Code Playgroud)

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

  1. func仅在A类对象上运行,应该成为A的成员.
  2. 应该在堆栈而不是堆上创建类A的对象.

还有其他想法吗?

Jam*_*lis 9

A应该在堆栈而不是堆上创建类的对象.

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

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

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

void func(int i)
{
    std::auto_ptr<A> pa(new A());
    pa->DoSomething(i);
}
Run Code Online (Sandbox Code Playgroud)

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

随着程序规模和复杂性的增加,手动资源管理很快变得非常困难.使用Scope-Bound Resource Management进行自动资源管理可以很好地扩展.

func只对类的对象进行操作,A并且应该成为A.

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

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

Herb Sutter通过std::string在他的"周刊大师"一文"Monoliths Unstrung"中分解课程来解释这一原则.

  • @ Steve314:我是[The Interface Principle](http://www.gotw.ca/publications/mill02.htm)的粉丝,其中"成员和非成员函数在逻辑上都是'一类'的一部分." (2认同)