c++ - 通过指向其非模板父类的指针将模板值分配给类模板

标签 c++ templates inheritance polymorphism virtual

我正在尝试制作 C++ Template可以存储模板值的类。但是,我需要在知道模板值的类型之前创建指向此类的指针。为此,我创建了一个摘要 Base模板类继承自的类。我创建指向 Base 的指针,当分配它们时,我使用 basePtr = new Template<TYPE> .

这里的问题是给Template赋值。 .我能想到的每一种方法(我喜欢使用重载赋值运算符)都需要一个以模板数据类型作为形式参数的方法。因为Template只能通过 Base 访问对象指针,我必须在 Base 中创建一个虚函数.但是,虚拟方法不能包含模板数据类型,Base中的虚拟方法的签名必须与 Template 的签名匹配的方法。

这是我想要的示例:

class Base {
    public:
        /* THIS IS ILLEGAL - can't have template virtual method
        template <class V>
        virtual void operator =(const V& newValue) = 0;
        */
};

template <class ValueType>
class Template : public Base {
    private:
        ValueType *value;
    public:
        void operator =(const ValueType& newValue) {
            *value = newValue;
        }
};

int main() {
    Base *theObject;                  // Datatype for template not known 
    theObject = new Template<string>; // At this point, it will be known

    // NOW, THIS DOESN'T WORK - no virtual assignment overload in Base
    *theObject = "Hello, world!";

    return 0;
}

如果我以完全错误的方式解决这个问题,或者如果我的方法很愚蠢,我深表歉意——这是我第一次涉足真正的 OOD。有没有办法解决我没有看到的这个问题?我知道我可以在 Base 中创建一长串纯虚函数用不同的输入类型重载赋值运算符,像这样:

virtual void operator =(const string& newValue) = 0;
virtual void operator =(const int& newValue) = 0;
virtual void operator =(const long& newValue) = 0;
...

但是,我希望用户能够将自定义类对象(或者更可能是指向这些对象的指针)插入到 Template::value 中。 ,我无法用上述方法完成。

最佳答案

实现您想要实现的目标的一种方法是使用 Boost.Any (一个著名的只有头文件的库)。下面是一个演示。代码一步步注释,大家应该能看懂, here 是一个活生生的例子:

#include <stdexcept>       // Standard header for exception classes
#include <string>          // Standard header for std::string
#include <boost/any.hpp>   // The Boost.Any library header
#include <iostream>        // This program prints some output

class Base
{
public:
    virtual void operator = (boost::any val) = 0;
    //                       ^^^^^^^^^^
    //                       This can hold (almost) "any" value

    // You need a virtual destructor if you want to delete objects
    // of subclasses of this class through a pointer to this class!
    virtual ~Base() { }
};

template <class ValueType>
class Template : public Base
{
private:
    ValueType value;
//  ^^^^^^^^^
//  I do not see why using a pointer in this case. Manual memory
//  management just complicates things. However, if your really
//  need to do it and your really know what you're doing, go ahead.
//  Just remember to delete your pointer at destruction and not to
//  dereference it before it points to an allocated object (in your
//  original text, both of these things are NOT done correctly).
public:
    virtual void operator = (boost::any val)
    {
        // Attempt a cast to detect if the value we are trying to
        // assign to this object is of the appropriate type...
        ValueType* pVal = boost::any_cast<ValueType>(&val);
        if (pVal == nullptr)
        {
            // ...it is not! Throw an exception...
            throw std::logic_error("Incompatible type");
        }

        // The value is OK: assign it...
        value = *pVal;
    }
};

int main()
{
    Base *theObject;
    theObject = new Template<std::string>;

    try
    {
        // This assignment will succeed...
        // Wrapping the string literal in a std::string object is necessary
        // because boost::any cannot be initialized from an array (and in C++
        // string literals are arrays of characters).
        *theObject = std::string("Hello, world!");

        // This assignment will fail!
        *theObject = 1;
    }
    catch (std::logic_error const& e)
    {
        // Handle the exception...
        std::cout << e.what();
    }

    delete theObject; // <=== DON'T FORGET THIS!

    return 0;
}

关于c++ - 通过指向其非模板父类的指针将模板值分配给类模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15125730/

相关文章:

c++ - 继承是否会破坏 C++ 中的封装

c++ - C++中组合关系的继承

c++ - 调整视频捕获的分辨率

c++ shared_ptr with std::function or double (*SOME_NAME)(double);

c++ - 来自 PDB 的 AST(例如通过 DIA)

c++ - 使用 c++ std::unique_ptr<> 或 std::shared_ptr<> 管理 objective-C 对象

c++ - 检索对象的函数运算符的参数类型

c++ - std::_Bind<std::_Mem_fn<void (ClassName::*)()>(ClassName*)> 是什么意思? (C++)

templates - 如何使用结构或变量值的字段作为模板名称?

python - 以两种或多种方式连接到服务,在Python中委托(delegate)方法执行