经过几个小时的搜索,我结束了这里。我有一个Container类,其指针指向Base类作为成员变量。这应该引用Spec1或另一个继承的Base类,我在这里省略了。类型应由构造函数中的参数确定(例如string,enum,int等)。
我读了很多关于动态内存分配的内容以及为什么应该尽可能避免它。这可以避免吗?在构造函数之后是不是破坏了任何通常的对象?或者设计理念是完全错误的?我来自Java :(提前致谢。
class Base{
public:
virtual ~Base(){}; // required?
virtual void doSomething() = 0;
};
class Spec1 : public Base {
public:
Spec1(){};
Spec1(int i){
// whatever
}
void doSomething(){
std::printf("hello world");
}
};
class Container{
public:
Container(String type_message){
if (type_message.compare("We need Spec1")){
m_type = new Spec1(1);
} // add more ifs for other types (Spec2, Spec3 etc.)
}
void doSomethingWithSpec(){
m_type->doSomething();
}
private:
Base* m_type;
};
int main (int argc, char **argv){
Container a ("We need Spec1");
a.doSomething();
}
答案 0 :(得分:1)
要求Container
了解每个可能的Base
派生类并不是一个好的设计。这就是工厂的功能。
让Container
将该对象存储为std::unique_ptr
,以避免内存泄漏和手动内存管理。
struct Base {
virtual ~Base() = default;
virtual void doSomething() = 0;
};
struct Spec1 : Base {
void doSomething() override {
std::printf("%s\n", __PRETTY_FUNCTION__);
}
};
// Factory function.
std::unique_ptr<Base> createBase(std::string const& type) {
if(type == "Spec1")
return std::unique_ptr<Base>(new Spec1);
throw std::runtime_error("Unknown type " + type);
}
class Container {
std::unique_ptr<Base> m_type;
public:
Container(std::string const& type)
: m_type(createBase(type))
{}
void doSomething(){
m_type->doSomething();
}
};
int main() {
Container a ("Spec1");
a.doSomething();
}
答案 1 :(得分:0)
构造函数与任何其他函数一样。当函数完成时,局部变量在堆栈中分配并超出范围,而动态内存分配在堆栈中完成,需要在函数完成之前显式释放(在C ++中而不是在Java中)。
但是在你的情况下
m_type = new Spec1(1);
new Spec1(1)
在堆中动态分配,并且在完成构造函数代码时不会被销毁。引用存储在类的成员变量中。因此,只要类Container
的实例在范围内,就可以引用分配给Spec1(1)
的内存。
比较只考虑其他情况。
Container(String type_message){
Base* m_type;
if (type_message.compare("We need Spec1")){
m_type = new Spec1(1);
} // add more ifs for other types (Spec2, Spec3 etc.)
}
一旦构造函数完成,m_type
将超出范围,但new Spec1(1)
仍将在堆中作为内存泄漏。