2013-11-25 112 views
1

假设我有这样的:通过它铸造派生并设置数据扩展基类

class Base { 
public: 
    int a; 
    Base() : a(5) {} 
}; 

template<class T> 
class Derived : public Base { 
public: 
    T value; 
}; 

以下作品中的代码,但我想知道什么可以使用这种方法的挑战:

Base * base = new Base; 
Derived<int> * derived = static_cast<Derived<int>*>(base); 
derived->value = 5; 
Derived<String> * derived1 = static_cast<Derived<String>*>(base); 
derived1->value = "test"; 

Derived<String> * newderived = static_cast<Derived<String>*>(base); 
std::cout << newderived->value; 
Derived<int> * newderived1 = static_cast<Derived<int>*>(base); 
std::cout << newderived1->value; 
//Output: test1 

或者我怎样才能以不同的,更安全的方式实现这样的事情。我想通过5个函数传递一个类来处理它。

+1

简单的解决方案,因为他们在c + +书籍编写,大多是好的。我建议你从简单的,基于继承的,无模板的最小示例开始。试试这个,再次问我们,_that_有什么问题。 – peterh

+2

“作品”在这里似乎有点夸大其辞。您正在覆盖未分配的内存,这会在程序的某个稍后阶段导致未指定但可能导致灾难性的问题。 (尝试使用valgrind获取更多详细信息。) – rici

+5

代码具有未定义的行为,如果它对您有用,那是因为您很不幸。 – john

回答

2

你在这里做的事情会在某个时候失败,因为派生类的大小大于基类,并且你在基类结束后编写。上述写入操作将覆盖属于另一个对象的内存。 您可以在基类中拥有一个SetValue()方法,并在派生类中实现它。

2

该代码不起作用。即使在铸造后你仍然会反对,因为你将它们构建为基础。演员们只是说:嗨,我知道这是一个Derived<xxx>,所以请您这样解释。这里你不知道,事实上你知道它不是Derived

要正确使用这些对象,您需要创建一个Derived<xxx>并在事后投射。如果您在此处使用dynamic_cast,则所有情况都应该返回为空,因为它们是Base

鉴于您想“通过5个功能传递课程”,您可能需要反向设置。创建Derived<xxx>对象并将它们保存为指向Base的指针。这可以在没有铸造的情况下工作。然后通过你的功能通过Base*。多态性将保证一切正常。

+0

我不应该创建派生类。所以我正在考虑为基类添加一个元素的容器。 – Gasim

+0

您正在定义“派生”类,但不应该使用它们?这对我来说没有任何意义。你必须更清楚地说明你想解决的实际问题。 – dornhege

+0

我的意思是,传递给函数的第一个对象通常是基类。所以,我摆脱了派生类,试图找到一种方法将多类型数组添加到可以随时分配的基类中。 – Gasim