C++ 你能使一个类的方法不可继承吗?
我有一个几何对象的基类,我自己使用它,但我也希望将该类继承到另一个类中,这是该对象的一种高级版本,因为它们共享很多逻辑。基本对象有几个静态创建方法(由于参数冲突,无法使用new),我不想继承这些方法。我能否以某种方式指定这些不被继承 编辑:包括一个示例C++ 你能使一个类的方法不可继承吗?,c++,inheritance,C++,Inheritance,我有一个几何对象的基类,我自己使用它,但我也希望将该类继承到另一个类中,这是该对象的一种高级版本,因为它们共享很多逻辑。基本对象有几个静态创建方法(由于参数冲突,无法使用new),我不想继承这些方法。我能否以某种方式指定这些不被继承 编辑:包括一个示例 struct Banana { float length; Banana() {} Banana(float length) { this->length = length; }
struct Banana {
float length;
Banana() {}
Banana(float length) {
this->length = length;
}
static Banana CreateByHalfLength(float halfLength) {
return Banana(halfLength * 2);
}
};
struct AdvancedBanana : Banana {
float bendAmt;
AdvancedBanana(float length, float bendAmt) {
this->length = length; this->bendAmt = bendAmt;
}
};
我不希望AdvancedBanana::CreateByHalfLength存在,但我确实希望Banana::CreateByHalfLength存在并且可以从类外访问。您所说的有点模糊,举个例子会很有用。 特别是因为您使用了static这个词,并且不清楚它的上下文是什么 不能阻止派生类继承基类的所有方法。您所能做的最好是使其成为需要基本对象参数的非成员。然后,在调用之前必须向下转换对象,但仍然可以调用它 你的建议似乎违反了利斯科夫替代原则。这意味着你应该重新考虑你的设计 也不是从A继承B。您可能需要一个基类Q,A和B都从该基类派生。[1] [1] Q是一个笑话,一些圣经学者认为有一些常见的未经证实的书,他们称之为Q,每个福音都是从中抄袭来的 编辑:附加 有了这个例子,有些事情就更清楚了。 让我对C++的理解做一些基本的修正。您说过,由于参数冲突,您有几种静态创建方法。我认为更好的说法是重载不能解决不同的构造方法。答案很简单:用两种方法之一扩展重载。 使用枚举或使用类。 第一个是通过附加ios::ate等在调用读/附加/读写类型流的流中看到的 就你而言:
enum BCT {halfLength,fullLength,quarterLength ...};
那就做吧
静态香蕉创建(浮动大小,BCT类型=全长){
开关(类型)
{
箱子全长:返回香蕉(尺寸);
箱半长:返回香蕉(尺寸*2);
箱长:返回香蕉(尺寸*4);
...
}
}
另一个版本是使用类来区分参数类型(我相信James Coplien称之为这些示例)
然后:
新类没有增加任何开销,但确实消除了重载歧义。我相信boost/std::filesystem将这种方式用于它的直接迭代器
话虽如此,一旦您决定如何创建实例,这些实例就不必是静态成员。他们可以是普通的构造函数,这将解决您的问题。大部分情况下。您仍然无法阻止AdvancedBanana实现半长度的创建方法,但编码人员会意识到他正在这样做
关于静态,静态成员函数是不访问this指针或某些语言称之为self的函数,即它们不访问特定实例的成员。事实上,在preC++98天内,在使用静态之前,人们所做的是做一些类似的事情:((Banana*)NULL)->静态函数(参数)代码>
在您的示例中,最好首先使用构造函数。静态构造函数最好留给真正需要它们的工厂
此外,在Mido的响应中,行:a.CreateByHalfLength(1)代码>可以编译,也可以不编译,我使用了这么多语言,有时我会被什么是非法的弄糊涂:(但是is显示了错误的想法。调用静态的正确方法是Banana::CreateByHalfLength(1);不取决于实例。尝试在子级中将函数重新声明为私有:
#include <iostream>
class Banana {
public:
float length;
float getLenght(){
return length;
}
void setLenght(float value){
length = value;
}
Banana() {}
Banana(float length) {
this->length = length;
}
static Banana CreateByHalfLength(float halfLength) {
return Banana(halfLength * 2);
}
};
class AdvancedBanana : public Banana {
public:
float bendAmt;
AdvancedBanana(float length, float bendAmt) {
this->length = length; this->bendAmt = bendAmt;
}
private:
static AdvancedBanana CreateByHalfLength(float halfLength);
};
int main()
{
// work
Banana a(1);
a.CreateByHalfLength(1);
AdvancedBanana b(0,1);
//will fail
// b.CreateByHalfLength(1);
};
#包括
香蕉班{
公众:
浮子长度;
float getLenght(){
返回长度;
}
无效设置长度(浮动值){
长度=值;
}
香蕉(){}
香蕉(漂浮长度){
这个->长度=长度;
}
静态半长(浮动半长){
返回香蕉(半身长*2);
}
};
高级班香蕉:公共香蕉{
公众:
浮动本达姆;
AdvancedBanana(浮动长度、浮动长度){
这个->长度=长度;这个->本达姆特=本达姆特;
}
私人:
静态提前半长(浮动半长);
};
int main()
{
//工作
香蕉a(1);
a、 CreateByHalfLength(1);
高级香蕉b(0,1);
//将失败
//b.半长度(1);
};
您只能这样做,使用AdvancedBanana的私有继承
#include <stdio.h>
struct Banana {
float length;
Banana() {}
Banana(float length) {
this->length = length;
}
static Banana CreateByHalfLength(float halfLength) {
return Banana(halfLength * 2);
}
};
struct AdvancedBanana : private Banana {
float bendAmt;
AdvancedBanana(float length, float bendAmt) {
this->length = length; this->bendAmt = bendAmt;
}
};
int main()
{
Banana b;
b.CreateByHalfLength(1);
AdvancedBanana bb(1, 2);
//bb.CreateByHalfLength(2);
return 0;
}
#包括
结构香蕉{
浮子长度;
香蕉(){}
香蕉(漂浮长度){
这个->长度=长度;
}
静态半长(浮动半长){
返回香蕉(半身长*2);
}
};
结构高级香蕉:私人香蕉{
浮动本达姆;
AdvancedBanana(浮动长度、浮动长度){
这个->长度=长度;这个->本达姆特=本达姆特;
}
};
int main()
{
香蕉b;
b、 CreateByHalfLength(1);
高级香蕉bb(1,2);
//bb.CreateByHalfLength(2);
返回0;
}
如果希望存在香蕉::CreateByHalfLength并可从类外部访问,则AdvancedBanana::CreateByHalfLength应该存在。
而且这也不是一个好的解决方案
另一方面,有人建议我设计两个或更多的类,或者根据您的需求从香蕉中取出函数
#include <stdio.h>
struct Banana {
float length;
Banana() {}
Banana(float length) {
this->length = length;
}
};
static Banana CreateByHalfLength(float halfLength) {
return Banana(halfLength * 2);
}
struct AdvancedBanana : private Banana {
float bendAmt;
AdvancedBanana(float length, float bendAmt) {
this->length = length; this->bendAmt = bendAmt;
}
};
int main()
{
Banana b = CreateByHalfLength(1);
AdvancedBanana bb(1, 2);
//bb.CreateByHalfLength(2);
return 0;
}
#包括
结构香蕉{
浮子长度;
香蕉(){}
香蕉(漂浮长度){
这个->长度=长度;
}
};
静态半长(浮动半长){
返回香蕉(半身长*2);
}
结构高级香蕉:私人香蕉{
浮动本达姆;
AdvancedBanana(浮动长度、浮动长度)
#include <stdio.h>
struct Banana {
float length;
Banana() {}
Banana(float length) {
this->length = length;
}
static Banana CreateByHalfLength(float halfLength) {
return Banana(halfLength * 2);
}
};
struct AdvancedBanana : private Banana {
float bendAmt;
AdvancedBanana(float length, float bendAmt) {
this->length = length; this->bendAmt = bendAmt;
}
};
int main()
{
Banana b;
b.CreateByHalfLength(1);
AdvancedBanana bb(1, 2);
//bb.CreateByHalfLength(2);
return 0;
}
#include <stdio.h>
struct Banana {
float length;
Banana() {}
Banana(float length) {
this->length = length;
}
};
static Banana CreateByHalfLength(float halfLength) {
return Banana(halfLength * 2);
}
struct AdvancedBanana : private Banana {
float bendAmt;
AdvancedBanana(float length, float bendAmt) {
this->length = length; this->bendAmt = bendAmt;
}
};
int main()
{
Banana b = CreateByHalfLength(1);
AdvancedBanana bb(1, 2);
//bb.CreateByHalfLength(2);
return 0;
}
struct Banana {
...
// Create a namesake wrapper for the `static` function and make it final
virtual
Banana CreateByHalfLength(float halfLength) final {
return CreateByHalfLengthImpl(halfLength);
}
static Banana CreateByHalfLengthImpl(float halfLength) {
return Banana(halfLength * 2);
}
};