Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 管理生命周期_C++_Templates_Design Patterns - Fatal编程技术网

C++ 管理生命周期

C++ 管理生命周期,c++,templates,design-patterns,C++,Templates,Design Patterns,我创建了一个容器来控制某些类型对象的生命周期(新建/删除),以避免任何编程错误。例如,删除对象时不会向容器发出任何通知。这些对象继承自同一基类(GreetingBase) 对于实现,我使用“模板技巧”: class-GreetingBase{ 公众: 虚拟空间sayHello(){ 标准::cout 为此可以使用模板,但使用接收指向基类的指针的函数更好 标准C++11方式-使用static\u assertwith.Without.C++11-boost等价物或您自己的元函数 旁注:如果使用智能

我创建了一个容器来控制某些类型对象的生命周期(新建/删除),以避免任何编程错误。例如,删除对象时不会向容器发出任何通知。这些对象继承自同一基类(GreetingBase)

对于实现,我使用“模板技巧”:

class-GreetingBase{
公众:
虚拟空间sayHello(){
标准::cout
  • 为此可以使用
    模板
    ,但使用接收指向基类的
    指针的函数更好
  • 标准C++11方式-使用
    static\u assert
    with.Without.C++11-boost等价物或您自己的元函数
  • 旁注:如果使用
    智能指针
    ,则无需编写此类容器

  • 为此可以使用
    模板
    ,但使用接收指向基类的
    指针的函数更好
  • 标准C++11方式-使用
    static\u assert
    with.Without.C++11-boost等价物或您自己的元函数

  • 旁注:如果您使用
    智能指针
    ,则无需编写此类容器

    我认为将
    addClass
    作为模板没有任何好处;这只意味着您将为每种不同类型实例化一个新的代码副本,并且您正在强制执行特定的构造函数调用

    只需将其设置为一个普通函数,并使用基类指针:

    void addClass(GreetingBase *o){
        items.push_back(o);
    }
    
    你的来电者也是

    container.addClass( new GreetingDerived() );
    
    而不是

    container.addClass<GreetingDerived>();
    
    container.addClass();
    
    我认为将
    addClass
    作为模板没有什么好处;它只是意味着您可以为每种不同的类型实例化一个新的代码副本,并且强制执行一个特定的构造函数调用

    只需将其设置为一个普通函数,并使用基类指针:

    void addClass(GreetingBase *o){
        items.push_back(o);
    }
    
    你的来电者也是

    container.addClass( new GreetingDerived() );
    
    而不是

    container.addClass<GreetingDerived>();
    
    container.addClass();
    
    使用模板来解决这个问题是一种常见的方法吗

    我不知道它是否常见,但它看起来足够合理。它确保您的容器只能包含指向使用
    new
    分配的对象的指针,这很好

    有什么缺点吗

    主要问题是您的容器破坏了。它有一个隐式生成的复制构造函数和复制赋值运算符,只需复制每个指针;这将为您提供两个容器对象,其析构函数都尝试删除相同的对象

    解决这一问题的最简单方法是删除这些成员函数,如果您使用的是2011年以前版本的语言,则将其声明为私有(没有实现)。如果您需要能够复制容器,则需要安全地实现它们

    就个人而言,我会使用智能指针,而不是滚动我自己的RAII容器;
    std::unique_ptr
    如果容器要具有独占所有权,
    std::shared_ptr
    如果您想要共享所有权,或者可能
    std::weak_ptr
    来保存由共享指针在其他地方管理的对象的非所有权引用在过去的uck中,
    unique\u ptr
    将不可用,但Boost提供了
    shared\u ptr
    弱\u ptr
    ,也与您的类似

    当“T”不是从“GreetingBase”派生时,报告更好错误消息的任何“标准方式”

    在C++11中,您也许可以使用静态断言,例如:

    static_assert(std::is_base_of<GreetingBase, T>::value, 
                  "Wrong type for GreetingContainer");
    
    错误消息类似于
    无法将which*转换为GreetingBase*
    ,这应该足够清楚

    使用模板来解决这个问题是一种常见的方法吗

    我不知道它是否常见,但它看起来足够合理。它确保您的容器只能包含指向使用
    new
    分配的对象的指针,这很好

    有什么缺点吗

    主要问题是您的容器破坏了。它有一个隐式生成的复制构造函数和复制赋值运算符,只需复制每个指针;这将为您提供两个容器对象,其析构函数都尝试删除相同的对象

    解决这一问题的最简单方法是删除这些成员函数,如果您使用的是2011年以前版本的语言,则将其声明为私有(没有实现)。如果您需要能够复制容器,则需要安全地实现它们

    就个人而言,我会使用智能指针,而不是滚动我自己的RAII容器;
    std::unique_ptr
    如果容器要具有独占所有权,
    std::shared_ptr
    如果您想要共享所有权,或者可能
    std::weak_ptr
    来保存由共享指针在其他地方管理的对象的非所有权引用在过去的uck中,
    unique\u ptr
    将不可用,但Boost提供了
    shared\u ptr
    弱\u ptr
    ,也与您的类似

    当“T”不是从“GreetingBase”派生时,报告更好错误消息的任何“标准方式”

    在C++11中,您也许可以使用静态断言,例如:

    static_assert(std::is_base_of<GreetingBase, T>::value, 
                  "Wrong type for GreetingContainer");
    

    错误消息将类似于
    无法将任何*转换为GreetingBase*
    ,这应该足够清楚。

    对于错误报告部分,请使用
    静态断言
    您的
    GreetingContainer
    不遵循,因此如果您复制它,您将得到泄漏。@Xeo我没有将它们放在示例中以保持小规模,但很好的通信nt无论如何,谢谢。对于错误报告部分,请使用
    static\u assert
    您的
    GreetingContainer
    不符合要求,因此如果您复制它,您将得到泄漏。@Xeo我没有将它们放在示例的小范围内,但无论如何都有很好的注释,谢谢。谢谢。我试图避免任何人可以从容器外部删除该实例。任何ggestions?@VíctorHerraiz:就你的代码而言,没有人可以直接访问指针,所以这不是问题。如果你添加了访问器,让它们返回引用或智能指针,而不是原始指针,所以没有人会错误地认为