将对象成员显式放在堆上(通过new)是否被视为不礼貌/不良做法?我认为您可能希望允许客户端选择内存区域来实例化对象.我知道可能存在堆成员可能被接受的情况.如果你知道某种情况可以描述一下吗?
Tod*_*lin 13
如果你有一个专为复制语义而设计的类,并且你不必要地分配/释放一堆内存,我可以看到这是不好的做法.但总的来说,事实并非如此.有很多类可以使用堆存储.只要确保你没有内存泄漏(在析构函数中释放内容,引用计数等),你就可以了.
如果您想要更多灵活性,请考虑让您的用户指定分配器.我会解释一下.
某些类(例如std::vector字符串,映射等)需要它们所代表的数据结构的堆存储.它不被认为是不礼貌的; 当你自动分配时vector,用户应该知道vector在调用构造函数时分配了一个缓冲区:
void foo() {
// user of vector knows a buffer that can hold at least 10 ints
// gets allocated here.
std::vector<int> foo(10);
}
Run Code Online (Sandbox Code Playgroud)
同样地,因为std::string,你知道有一个内部堆分配char*.每个string实例是否有一个通常取决于STL实现; 通常他们被引用计数.
但是,对于几乎所有的STL类,用户都可以选择放置的位置,因为它们可以指定分配器. vector是这样定义的:
template <typename T, typename Alloc = DefaultAllocator<T> >
class vector {
// etc.
};
Run Code Online (Sandbox Code Playgroud)
在内部,vector使用Alloc(默认为默认分配器用于T的任何内容)来分配缓冲区和它可能需要的其他堆存储.如果用户不喜欢默认分配策略,他们可以指定自己的一个:
vector<int, MyCustomAllocator> foo(10);
Run Code Online (Sandbox Code Playgroud)
现在,当构造函数分配时,它将使用MyCustomAllocator而不是默认值.以下是编写自己的STL分配器的一些细节.
如果您担心在类中使用堆来存储特定存储可能是"不礼貌",您可能需要考虑为您的类的用户提供这样的选项,以便他们可以指定如何分配事物.您的默认策略不符合他们的需求.
Mat*_*vis 10
我根本不认为这是不好的做法.您可能希望通过new显式分配成员变量的原因有很多种.这里有几个我的头顶.
另一方面,如果您的用户创建了很多类的实例以供在堆栈上使用,那么使用对象代替成员变量的指针将是有利的,因为堆分配/解除分配比较慢.考虑到上面的第一个子弹,在这种情况下避免堆更有效.