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

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


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


func仅在类A的对象上操作,应成为A的成员。
类A的对象应该在堆栈上而不是堆上创建。


还有其他想法吗?

最佳答案

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类,从而解释了这一原理。

关于c++ - 您看到此C++代码有任何问题吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4236473/

10-12 18:46