初始化派生 class 虚函数返回的内联静态变量的最佳方法
Best way to initialize inline static variable returned by derived class virtual function
最初我有 m_damage 作为基础 class Projectile 中的 class 成员,在每个派生的 class 中分配初始化列表中的值并且有一个getter 基函数 class.
但后来我意识到我不需要派生 class 的每个实例都持有 m_damage 的副本,因为它对于每个派生 class 的所有实例都是相同的值,所以我需要创建值 static
并在 virtual
函数覆盖中让每个派生 class return 它。
在网上和此处进行研究后,我相信 inline static const
变量是可行的方法。但是将它作为 class 成员或 class 常量有什么好处吗?或者还有其他更好的方法吗?我只想通过 Projectile 中的私有虚函数访问值。
projectile.h 文件
class Projectile
{
private:
virtual int getDamage() const = 0;
}
火箭.h文件
class Rocket : public Projectile
{
private:
// inline static const auto ROCKET_DAMAGE = 400; <---- make it a class member?
virtual int getDamage() const final override;
}
火箭 .cpp 文件
// inline static const auto ROCKET_DAMAGE = 400; <---- make it a class constant?
int Rocket::getDamage() const
{
return ROCKET_DAMAGE;
}
这是静态 class 变量的一个很好的用例。如果它是一个常量,并且对于 class 的所有对象都是相同的值,如果它是一个数据成员,它只会浪费内存。我会继续并使它 constexpr
所以它在编译时分配,并且可用于编译时计算,如果你需要它(假设你有一个启用 C++17 的编译器}:
constexpr static auto ROCKET_DAMAGE = 400;
解决这个问题的另一种方法是不使用静态变量,而是 return 直接从虚函数中获取值:
int Rocket::getDamage() const
{
return 400;
}
使用静态 class 变量将使将来更改值变得稍微容易一些,如果您需要:直接修改头文件比拖网实现文件更容易并找到正确的函数定义。但是,如果头文件在多个文件中是 #include
-d,这可能是负面的,因为这将需要使用此头文件重新编译所有源文件,这意味着编译时间更长。
从 API 设计的角度来看,常量是一个实现细节。因此,您可能希望将此实现细节(即常量)隐藏在 .cpp
文件中已有的成员函数定义之后。
在rocket.hpp
中:
class Rocket: public Projectile {
private:
virtual int getDamage() const final override;
};
在rocket.cpp
中:
static constexpr auto ROCKET_DAMAGE = 400; // not exposed to client
int Rocket::getDamage() const {
return ROCKET_DAMAGE;
}
请注意,如下例所示,将常量 ROCKET_DAMAGE
作为数据成员会将其公开给客户端:
class Rocket: public Projectile {
private:
inline static const auto ROCKET_DAMAGE = 400;
};
常量可能会被编译到客户端的代码中。这意味着每次更改常量 ROCKET_DAMAGE
.
的值时都需要重新编译客户端代码
相反,如果常量ROCKET_DAMAGE
因为隐藏在.cpp
文件中而没有通过头文件暴露给客户端(如前一种情况),改变的值该常量不可能需要重新编译客户端代码。
最初我有 m_damage 作为基础 class Projectile 中的 class 成员,在每个派生的 class 中分配初始化列表中的值并且有一个getter 基函数 class.
但后来我意识到我不需要派生 class 的每个实例都持有 m_damage 的副本,因为它对于每个派生 class 的所有实例都是相同的值,所以我需要创建值 static
并在 virtual
函数覆盖中让每个派生 class return 它。
在网上和此处进行研究后,我相信 inline static const
变量是可行的方法。但是将它作为 class 成员或 class 常量有什么好处吗?或者还有其他更好的方法吗?我只想通过 Projectile 中的私有虚函数访问值。
projectile.h 文件
class Projectile
{
private:
virtual int getDamage() const = 0;
}
火箭.h文件
class Rocket : public Projectile
{
private:
// inline static const auto ROCKET_DAMAGE = 400; <---- make it a class member?
virtual int getDamage() const final override;
}
火箭 .cpp 文件
// inline static const auto ROCKET_DAMAGE = 400; <---- make it a class constant?
int Rocket::getDamage() const
{
return ROCKET_DAMAGE;
}
这是静态 class 变量的一个很好的用例。如果它是一个常量,并且对于 class 的所有对象都是相同的值,如果它是一个数据成员,它只会浪费内存。我会继续并使它 constexpr
所以它在编译时分配,并且可用于编译时计算,如果你需要它(假设你有一个启用 C++17 的编译器}:
constexpr static auto ROCKET_DAMAGE = 400;
解决这个问题的另一种方法是不使用静态变量,而是 return 直接从虚函数中获取值:
int Rocket::getDamage() const
{
return 400;
}
使用静态 class 变量将使将来更改值变得稍微容易一些,如果您需要:直接修改头文件比拖网实现文件更容易并找到正确的函数定义。但是,如果头文件在多个文件中是 #include
-d,这可能是负面的,因为这将需要使用此头文件重新编译所有源文件,这意味着编译时间更长。
从 API 设计的角度来看,常量是一个实现细节。因此,您可能希望将此实现细节(即常量)隐藏在 .cpp
文件中已有的成员函数定义之后。
在rocket.hpp
中:
class Rocket: public Projectile {
private:
virtual int getDamage() const final override;
};
在rocket.cpp
中:
static constexpr auto ROCKET_DAMAGE = 400; // not exposed to client
int Rocket::getDamage() const {
return ROCKET_DAMAGE;
}
请注意,如下例所示,将常量 ROCKET_DAMAGE
作为数据成员会将其公开给客户端:
class Rocket: public Projectile {
private:
inline static const auto ROCKET_DAMAGE = 400;
};
常量可能会被编译到客户端的代码中。这意味着每次更改常量 ROCKET_DAMAGE
.
相反,如果常量ROCKET_DAMAGE
因为隐藏在.cpp
文件中而没有通过头文件暴露给客户端(如前一种情况),改变的值该常量不可能需要重新编译客户端代码。