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/