C++ 将属性传递给基类的机制
将属性从派生类传递到基类的机制是什么,以便:C++ 将属性传递给基类的机制,c++,oop,derived-class,C++,Oop,Derived Class,将属性从派生类传递到基类的机制是什么,以便: 基本用户可以访问它们 它们可以很容易地存储在STL容器中 外部的任何人都只能在派生类上访问它们 有效性不是很有价值 属性是一个与派生类的每个对象相关的常量。可以虚拟执行,也可以非虚拟执行。但要回答其中哪一个是最好的,让我们检查一下您的示例: class自行车:公共车辆 { 公众: 自行车(可行驶车辆和表,编号):基本车辆(表,编号){} 虚拟浮点getMaxSpeed()常量{return 40.0f;}//常量 虚拟浮点getWeight()常
- 基本用户可以访问它们
- 它们可以很容易地存储在STL容器中
- 外部的任何人都只能在派生类上访问它们
- 有效性不是很有价值
属性是一个与派生类的每个对象相关的常量。可以虚拟执行,也可以非虚拟执行。但要回答其中哪一个是最好的,让我们检查一下您的示例:
class自行车:公共车辆
{
公众:
自行车(可行驶车辆和表,编号):基本车辆(表,编号){}
虚拟浮点getMaxSpeed()常量{return 40.0f;}//常量
虚拟浮点getWeight()常量{return 10.0f;}//常量
虚浮点getLength()常量{return 2.3f;}//常量
虚拟int getWheels()常量{return 2;}//常量
};
这些函数中的每一个都返回一个常量,但仍然需要一个虚拟调用来获取该常量。这是一种糟糕的做法,因为您需要执行(昂贵的)虚拟调用来获取每个值
更好的方法:使用struct
相反,最好将这些常量传递给父类的构造函数,并将这些常量存储在基类中。这样,您根本不需要访问BaseVehicle
的vtable
,只需直接在基类内部访问即可。像这样:
struct vehiclests{
浮动最大速度;
浮重;
浮子长度;
int车轮;
};
//BaseVehicle的构造函数现在变成:
基本车辆(车辆表、编号、车辆测试统计)
或者,您只能在基本车辆
中创建一个虚拟
功能:
virtualvehiclests getStats()const=0;
这肯定比创建四个单独的函数要好
替代方法:使用enum
您还可以将表示车辆类型的enum
传递给父级。例如:
enum类车辆类型{
自行车,
汽车
};
//BaseVehicle的构造函数现在变成:
基本车辆(车辆表、编号、车辆类型统计)
然后全局存储统计信息:
static const std::map globalStatsMap;
如果您有大量的统计数据,并且不想增加基类的内存大小,那么这是一个非常好的方法。现在,您根本不需要
BaseVehicle
的实例,仍然可以根据类型查找属性。从所示内容来看,您根本不需要继承:
struct VehicleAttributes
{
float maxSpeed;
float weight;
float length;
int wheelsCount;
};
class Vehicle
{
private:
Vehicle(VehicleTable& table, Number number, const VehicleAttributes& attributes): m_image(attributes.length, attributes.wheelsCount), m_attributes(&attributes)
{
table.registerVehicle(*this, number);
}
public:
static Vehicle BiCycle(VehicleTable& table, Number number)
{
static const VehicleAttributes bicycleAttributes{40, 10, 2.3, 2};
return Vehicle(table, number, bicycleAttributes);
}
static Vehicle Car(VehicleTable& table, Number number)
{
static const VehicleAttributes carAttributes{88, 42, 2.5, 4};
return Vehicle(table, number, carAttributes);
}
const VehicleAttributes& getAttributes() const { return *m_attributes; }
private:
Image m_image;
const VehicleAttributes* m_attributes = nullptr;
float m_speed = 0; // the current speed
};
如果您的问题是“将属性从派生类传递到基类的机制是什么?”那么有两种方法可以做到这一点
#包括
阶级基础
{
公众:
基本(常量字符*a)
{
代码中没有“与派生类的每个对象相关的常量”,因此代码和文本之间的联系不清楚。您发布的代码有什么问题/缺失?@idclev463035818虚拟函数表示常量。因此,问题是如何在基类构造函数中访问它们?或者使用什么来代替虚拟函数?@idclev463035818 Yes我无法再次跟随您的参数st要点3.如果你需要一个值来构造一个对象,那么将其作为参数传递给构造函数是自然的,而不是“阻碍的”。如果你不想让构造函数公开,你可以将其设置为受保护的。此外,这并不“假设允许它创建具有任何属性的基本对象”(至少与任何构造函数的情况不同),基类和派生类都仍然可以检查有效参数并相应地执行操作。此代码非常糟糕。您仍然在调用getLength()
和getWheels()
在初始值设定项列表中,您拼错了VehicleAttributes
,您拼错了VehicleAttributes
,您没有用地址初始化m_属性
,并且默认情况下为其分配nullptr
,即使它总是初始化的。@J.Schultke:我没有意识到以前的构造函数调用这是虚拟方法。我希望我修复了拼写错误(更容易用IDE/compiler捕获;-)。我忘记了&
获取地址(也有拼写错误:/)。我更喜欢默认为nullptr
初始化每个指针/内置,即使总是初始化(在出错时更容易调试)。