Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you make a method of a class non inheritable?

I have a base class of a geometric object which I use on its own but I also want to inherit the class into another one thats sort of an advanced version of the object since they share a lot of logic. The base object has several static creation methods (cannot use new due to argument conflicts), I don't want to inherit those. Can I specify somehow that those are not to be inherited?

EDIT: to include an example

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

I don't want AdvancedBanana::CreateByHalfLength to exist while I do want Banana::CreateByHalfLength to exist and be accessible from outside the class.

like image 978
user81993 Avatar asked Sep 28 '22 06:09

user81993


3 Answers

Try this redclare the function as private in the child:

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

    };
like image 88
Mido Avatar answered Nov 15 '22 10:11

Mido


You can only do like this, using private inherit for 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;
}

AdvancedBanana::CreateByHalfLength should be exist, if you want Banana::CreateByHalfLength to exist and be accessible from outside the class. And also this is not a good solution.

On another way I am suggested, to design two or more classes or to take the functions out of Banana, for your demand. It will be something like this.

#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;
}
like image 42
sunnyleevip Avatar answered Nov 15 '22 08:11

sunnyleevip


If you want to automatically restrict the derived classes to overload the static Banana CreateByHalfLength(float halfLength); then a very quick way is to encapsulate that function inside a virtual final method.

e.g.

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

With this arrangement, now any derived class will not be able to create a similar function static or non-static.
Here is a demo.

The drawback of this approach is that you are adding a function overhead of being virtual as well as being called with an unused object.

like image 24
iammilind Avatar answered Nov 15 '22 09:11

iammilind