2015-03-13 55 views
1

我面临以下情况:摘要如何处理返回对象

class Base{ 
     virtual void Stuff() = 0; 
}; 

class ConcreteA : public Base{ 
     void Stuff() {}; 
}; 

class ConcreteB : public Base{ 
     void Stuff() {}; 
}; 

class Context { 
     Base exec() { 
      ConcreteA conc_a(); 
      return a; 
     } 
}; 

当然编译器给我一个错误,因为Base是抽象的。不过,我需要exec()返回一个Base类型。我知道我可以使用指针或引用使编译器高兴,但由于对象ConcreteA是在exec()中创建的,因此通过值返回是避免悬挂引用或具有未定义所有权的指针的最佳方法。

有没有办法避免使用指针或引用来处理这种情况?

+0

不,没有办法避免引用或指针,如果你想返回“基”类型。 – 2015-03-13 17:00:51

+0

'std :: unique_ptr'? – 2015-03-13 17:08:59

回答

3

这看起来像是一个完美的,简单的使用案例std::unique_ptr。这里是一个C++ 14例如:当在base_ptrmain超出范围

#include <memory> 
#include <iostream> 

class Base{ 
public: 
     virtual ~Base() {} 
     virtual void Stuff() = 0; 
}; 

class ConcreteA : public Base{ 
     void Stuff() { std::cout << "ConcreteA::Stuff\n"; }; 
}; 

class ConcreteB : public Base{ 
     void Stuff() { std::cout << "ConcreteB::Stuff\n";}; 
}; 

class Context { 
public: 
     std::unique_ptr<Base> exec() { 
      return std::make_unique<ConcreteA>(); 
     } 
}; 

int main() 
{ 
    Context c; 
    auto base_ptr = c.exec(); 
    base_ptr->Stuff(); 
} 

存储器被自动删除。

请注意,我也使Base析构函数虚拟。也许你只是为了简洁而将它留在你的代码示例中,但它的重要性应该被强调,并且我认为它应该保留在简短的示例代码中。

+0

可能值得注意添加虚拟析构函数的重要性。 – 2015-03-13 17:26:29

+0

@MikeSeymour:对。我添加了一些答案。 – 2015-03-13 17:28:49

+0

@Mike Seymour你是什么意思?当Context超出范围时,unique_ptr应该被自动删除,我错了吗? – gcswoosh 2015-03-13 17:30:02