C++ 你能使一个类的方法不可继承吗?

C++ 你能使一个类的方法不可继承吗?,c++,inheritance,C++,Inheritance,我有一个几何对象的基类,我自己使用它,但我也希望将该类继承到另一个类中,这是该对象的一种高级版本,因为它们共享很多逻辑。基本对象有几个静态创建方法(由于参数冲突,无法使用new),我不想继承这些方法。我能否以某种方式指定这些不被继承 编辑:包括一个示例 struct Banana { float length; Banana() {} Banana(float length) { this->length = length; }

我有一个几何对象的基类,我自己使用它,但我也希望将该类继承到另一个类中,这是该对象的一种高级版本,因为它们共享很多逻辑。基本对象有几个静态创建方法(由于参数冲突,无法使用new),我不想继承这些方法。我能否以某种方式指定这些不被继承

编辑:包括一个示例

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);
  }
};