选择两个只能由new
创建的类。一类是基础,另一类是衍生物。派生类只添加方法。
class Base
{};
class Derived : public Base
{};
Base * b = new Base{}
Derived * d = covert( b );
// - or -
Base * b = new Base{};
convert( b ); // converts Base to Derived
Derived * d = dynamic_cast<Derived *>(b);
我想要做的是获取已分配的Base
类数据,并通过某种方法或函数convert
扩展/包装衍生物。
更新 构建嵌入式系统的内存很少,所以我尽我所能来减少内存分配。我只是想知道是否有一种方法可以扩展基类已经分配的内存并用衍生物包装它。
更新更新 虽然嵌入式系统是ARM,而我目前正在使用LLVM编译器,但未来可能并非如此。因此,首选符合标准的方式。
答案 0 :(得分:2)
在C ++中无法升级类。您可能想要做的是 - 就像您说的那样 - 在Base
中包裹Derived
:
class BaseInterface { ... };
class DerivedInterface: public BaseInterface { ... };
class Base: public BaseInterface { ... };
class Derived: public DerivedInterface {
private:
Base* base;
public:
Derived(Base* useBase): base(useBase) {}
~Derived() { delete base; }
// implement using base
};
并使用它:
Base* object = new Base(...);
// use object with base functionality
object = new Derived(object);
// use object with derived functionality
delete object; // free both base and derived memory
答案 1 :(得分:2)
如果我理解你的问题,一个可能的解决方案是使用聚合而不是继承。
class Base
{/*has only the data*/}
class Derived
{
Base &base;
Derived(Base &b) : base(b) {}
//now methods from derived will use the data members from instance passed in constructor
//if is possible the Derived needs to be a friend class of Base in case there are no getter for all members
}
如果需要,我们可以使用智能指针代替引用。 这样就可以通过构造一个使用Base对象数据的新Derived对象来避免强制转换。
答案 2 :(得分:1)
派生类只添加方法。
那个班级没有意义。完全没有。
您可以使用派对:
virtual
方法(从而自定义行为)=&gt;好在你的特定情况下?这没用。它不会将任何带到表中。如果您希望向基类添加新功能,请实现免费功能。作为奖励,摆脱派生类,你也将摆脱投射的需要。
答案 3 :(得分:1)
感谢C ++ 11
,这是一个潜在的选择class Base
{
pubilc:
Data data;
Base( Base && base ) : data( std::move( base.data ) ) {}
};
class Derived : public Base
{
pubilc:
static Derived * convert( Base *& base )
{
Derived * d = new Derived{ std::move( *base ) };
delete base;
base = d;
return d;
}
};
虽然这不是我希望的记忆方式,但据我所知,这只是一个小小的打击。通过使用move构造,唯一的开销是在删除旧的Derived
对象之前创建新的Base
对象。
在完成任何事情之前应该进行检查,但现在这样做。
答案 4 :(得分:0)
您可以添加一个辅助类,它是基类的朋友,并为其添加额外的功能,例如。
class Base
{
friend class BaseHelper;
// ....
};
class BaseHelper
{
public:
// all functions can access data into Base objects:
void f(const Base& b) const; // can only read data in b, not change it
void g(Base& b); // can change data in b
}
答案 5 :(得分:0)
Derived *d =static_cast<Derived *>(b); //? :-/
Much more detailed explanation of what's happening under the hood
更新:
Stack Overflow - Downcasting using the static_cast in c++
Downcasting in C++ using static_cast
规格:
“指向cv1 B的指针”类型的右值,其中B是类类型,可以是 转换为“指向cv2 D的指针”的右值,其中D是一个类 如果是有效的标准转换,则从B派生(第10条) “指向D的指针”到“指向B的指针”存在(4.10),cv2是相同的 cvqualification as或更高的cvqualification,cv1和B不是 D的虚基类。转换空指针值(4.10) 到目标类型的空指针值。如果是左值 键入“指向cv1 B的指针”指向实际上是其子对象的B. D类型的对象,结果指针指向封闭 类型为D.的对象。否则,转换的结果是未定义的。
仅适用于LLVM:
http://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html - 允许DOWNCASTING(不是未定义的行为,因为它不使用C ++ RTTI)。
没有符合标准的转发方式:
class Parent{
public: void gotoWork(){ cout << doWork(); }
};
class Child: public Parent{
public: void gotoSchool(){ cout << attendClasses();}
};
Parent *p = new Parent();
Child *ch = static_cast<Child*> p;
//now child has to go work? :-(
修改强>
除了所有其他方式,为什么不放两个对象? “基地”之一 和另一个“衍生”类型的UNION?
PS:符合语言规范。
答案 6 :(得分:0)
通过我的许多答案,我们共同的共识是,我应该按照我所说的去做,并将我的Base
课程包装在Derived
课程中。我没有这样做的原因是我会失去你继承的特定行为。此行为是将Derived
类的指针设置为类型Base
的指针,这将在我进行某种转换后发生,这将使Base
类转换为{Derived
类1}} class。
A在我own的解决方案上遇到了挫折 - 虽然显然它可能无法编译 - 并且还有许多其他good ideas。最后,我觉得有点慢,因为对于我的情况,我的Derived
类没有覆盖任何虚拟方法no benefit of using inheritance。最好的方法是使用合成。
class Base
{
// some nice implementation
};
class Derived
{
public:
Derived( Base && base )
{
this->_base = base;
}
Base & base()
{
return _base;
}
private:
Base _base;
};