我正在写一个图书馆,并在这我有一类基类.任何人使用的图书馆将建立自己的继承的类从BaseClass.我有另外一个类,让我们叫它经理,它拥有一个矢量的基类指针,其中可以保持的任何对象从基类.

管理类必须处理的创造和毁灭的任何对象添加到其BaseClass的矢量。这是因为任何目的矢量可以在任何时候被删除,并在管理本身也可以被删除。因此,用户对该图书馆不能添加一个目经理的基类矢量,由它传递一个指向一个已经存在的对象从基类.好吧,事实上,我可能允许的用户做到这一点。但是,将涉及复制一个虚拟的对象,这是我宁愿不做的。

为解决这个,我试图使用一个模板功能。使用者应该通过类型的对象从基类,当试图将它添加到经理的矢量。这是我目前所拥有的。

//Manager.h
#include <vector>
#include "BaseClass.h"
#include <typeinfo>

class Manager {
    //Vector holding pointers to any objects inherited from BaseClass
    vector<BaseClass*> baseClasses;

    //Template function that needs to add NEW object to baseClass vector
    //This I'm having problems with
    template<class T>
    BaseClass* Add() {
        BaseClass* baseClass = new T();
        baseClasses.push_back(baseClass);
        return baseClass;
    }

    //Template function that gets object from baseClass vector
    //This works fine
    template<class T>
    BaseClass* Get() {
        for (int i = 0; i < baseClasses.size(); i++) {
            if (typeid(*baseClasses[i]) == typeid(T)) {
                return baseClasses[i];
            }
        }
        return NULL;
    }
};

例如,用户应该这样做的时候增加或得到一个对象从管理的基类的矢量。基类实现来自BaseClass

Manager manager;
//Add a new DerivedClass object to Manager's vector
manager.Add<DerivedClass>();
//Get a pointer to the DerivedClass object that was just added
DerivedClass* derivedClass = (DerivedClass*)manager.Get<DerivedClass>();

我得()功能正常工作。什么我需要知道的是,如何可以得到我Add()function工作?帮助,将不胜感激。

有帮助吗?

解决方案

有相当多的事情尚不清楚对你的设计,但如果问题是,是否可以强制执行的类型 T 在件的功能templa Add 可以强制执行从 BaseClass, ,选择很简单:

  • 什么都不做,编译器会很乐意的抱怨就行 BaseClass* baseClass = new T();
  • 添加一个静态的主张,使这种更明显的
  • 用花式SFINAE技巧,以去除功能设置的超载

我会去任何一个第一二。静态的主张可能是拼写为:

static_assert(std::is_base_of<BaseClass,T>::value);

该SFINAE伎俩,我真避免,因为它将使代码的更多混淆,但可以实现为:

template <class T>
typename std::enable_if<std::is_base_of<BaseClass,T>::value,T*>::type
Add() {
   baseClasses.push_back(new T());
   return baseClasses.back();
}

(注意,我改变了回返类型 T*, ,对象是 T, 为什么一回 BaseClass*?这同样适用于 Get 功能没有点在返回 BaseClass*, 当你知道的对象真的是一个 T)

现在的实际问题是复杂得多,因为你的设计是积极避免考虑的所有权,这你不应该。想想所有权的对象,并确保有一个明确的拥有者(或者说,资源是共享)。一旦你知道谁拥有对象、创建一个协议对其余的代码通知的所有者当一个对象需要予以删除。如果你允许 任何 代码以删除的指针,你会遇到不确定的行为很快。

其他较小的问题可以包括事实上,你正在实施的所有组成部分有一个默认的构造,这可能会或不适当的。你可以简化这种限制具有非模板 Add 需要指针,并让的呼叫者创建的对象的方式,请他们。

使用 typeid 通常的代码-闻闻我不认为这是例外,也许你会更好通过设计类型分层结构中,你可以问的对象是什么,而不是运行 typeid.如果你真的确定作出的界面,基于类型,然后再考虑是否 dynamic_cast 可能会更好。它将更innefficient,但是如果你有多个级别的继承,它会让你回来的大多数派生的对象为中间体的对象

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top