C++ 基类指针指向使用已分配内存的派生类指针
选取两个只能由C++ 基类指针指向使用已分配内存的派生类指针,c++,c++11,C++,C++11,选取两个只能由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
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*b=新的Base{}
派生*d=隐蔽(b);
//-或-
Base*b=新的Base{};
转换(b);//将基转换为派生
导出*d=动态_投射(b);
我要做的是获取已分配的Base
类数据,并通过某种方法或函数convert
使用导数进行扩展/换行
更新:
为嵌入式系统构建内存是稀缺的,所以我正在尽我所能减少内存分配量。我只是想知道是否有一种方法可以扩展已经分配了内存的基类,并用派生函数包装它
更多更新:
虽然嵌入式系统是ARM,我目前正在使用LLVM编译器,但将来可能不会这样。因此,首选符合标准的方法。您可以添加一个助手类,它是基类的朋友,并向该类添加额外的函数,例如
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
}
您可以添加一个助手类,它是基类的朋友,并向其添加额外的函数,例如
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
}
<>在C++中不可能使用类。您可能想做的是—就像您所说的—将
Base
包装到派生的:
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
<>在C++中不可能使用类。您可能想做的是—就像您所说的—将Base
包装到派生的:
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
如果我正确理解您的问题,一个可能的解决方案是使用聚合而不是继承
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
}
如果需要,我们可以使用智能指针来代替引用。
通过这种方式,您可以通过构造一个新的派生对象来避免强制转换,该对象使用来自基本对象的数据。如果我正确理解您的问题,一个可能的解决方案是使用聚合而不是继承
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
}
Derived *d =static_cast<Derived *>(b); //? :-/
如果需要,我们可以使用智能指针来代替引用。
通过这种方式,您可以通过构造一个新的派生对象来避免强制转换,该派生对象使用来自基本对象的数据。Derived*d=static_cast(b);/?:-/
Derived *d =static_cast<Derived *>(b); //? :-/
更新:
规格:
类型为“指向cv1 B的指针”的右值,其中B是类类型,可以
转换为“指向cv2 D的指针”类型的右值,其中D是一个类
从B派生(第10条),如果从
存在“指向D的指针”到“指向B的指针”(4.10),cv2相同
CVA鉴定为或大于cv1的CVA鉴定,且B不是
D的虚拟基类。转换空指针值(4.10)
指向目标类型的空指针值。如果
类型“指向cv1 B的指针”指向实际上是的子对象的B
类型为D的对象,结果指针指向封闭的
类型为D的对象。否则,强制转换的结果未定义
仅限LLVM:
允许向下转换(不是未定义的行为,因为它不使用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? :-(
类父类{
public:void gotoWork(){coutDerived*d=static_cast(b);/?:-/
更新:
规格:
类型为“指向cv1 B的指针”的右值,其中B是类类型,可以
转换为“指向cv2 D的指针”类型的右值,其中D是一个类
从B派生(第10条),如果从
存在“指向D的指针”到“指向B的指针”(4.10),cv2相同
CVA鉴定为或大于cv1的CVA鉴定,且B不是
D的虚拟基类。转换空指针值(4.10)
指向目标类型的空指针值。如果
类型“指向cv1 B的指针”指向实际上是的子对象的B
类型为D的对象,结果指针指向封闭的
类型为D的对象。否则,强制转换的结果未定义
仅限LLVM:
允许向下转换(不是未定义的行为,因为它不使用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? :-(
类父类{
public:void gotoWork(){cout
派生类只添加方法
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);
那么这门课就毫无意义了
您可以使用派生来:
- 覆盖
virtual
方法(从而定制行为)=>良好
- 扩展基类的数据=>Bad,代码重用应该使用组合,但仍然有效
在你的特殊情况下?它只是无用的。它不会带来任何东西。如果你想给基类添加新功能,那么就实现自由函数。作为奖励,摆脱派生类,你也将摆脱强制转换的需要
派生类只添加方法
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);
那么这门课就毫无意义了
您可以使用派生来:
- 覆盖
virtual
方法(从而定制行为)=>良好
- 扩展基类的数据=>Bad,代码重用应该使用组合,但仍然有效
在你的特殊情况下?它只是无用的。它不会带来任何东西。如果你想给基类添加新功能,那么就实现自由函数。作为奖励,摆脱派生类,你也将摆脱强制转换的需要。多亏了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构造,唯一的开销是在删除旧的基对象之前创建一个新的派生的
对象
在做任何事情之前都应该检查一下,但是这个