Why can't I inherit from int in C++?

前端 未结 19 2114
不知归路
不知归路 2020-12-02 18:24

I\'d love to be able to do this:

class myInt : public int
{

};

Why can\'t I?

Why would I want to? Stronger typing. For example, I

相关标签:
19条回答
  • 2020-12-02 18:35

    As others I saying, can't be done since int is a primitive type.

    I understand the motivation, though, if it is for stronger typing. It has even been proposed for C++0x that a special kind of typedef should be enough for that (but this has been rejected?).

    Perhaps something could be achieved, if you provided the base wrapper yourself. E.g something like the following, which hopefully uses curiously recurring templates in a legal manner, and requires only deriving a class and providing a suitable constructor:

    template <class Child, class T>
    class Wrapper
    {
        T n;
    public:
        Wrapper(T n = T()): n(n) {}
        T& value() { return n; }
        T value() const { return n; }
        Child operator+= (Wrapper other) { return Child(n += other.n); }
        //... many other operators
    };
    
    template <class Child, class T>
    Child operator+(Wrapper<Child, T> lhv, Wrapper<Child, T> rhv)
    {
        return Wrapper<Child, T>(lhv) += rhv;
    }
    
    //Make two different kinds of "int"'s
    
    struct IntA : public Wrapper<IntA, int>
    {
        IntA(int n = 0): Wrapper<IntA, int>(n) {}
    };
    
    struct IntB : public Wrapper<IntB, int>
    {
        IntB(int n = 0): Wrapper<IntB, int>(n) {}
    };
    
    #include <iostream>
    
    int main()
    {
        IntA a1 = 1, a2 = 2, a3;
        IntB b1 = 1, b2 = 2, b3;
        a3 = a1 + a2;
        b3 = b1 + b2;
        //a1 + b1;  //bingo
        //a1 = b1; //bingo
        a1 += a2;
    
        std::cout << a1.value() << ' ' << b3.value() << '\n';
    }
    

    But if you take the advice that you should just define a new type and overload the operators, you might take a look at Boost.Operators

    0 讨论(0)
  • 2020-12-02 18:37

    Well, you don’t really need to inherit anything which hasn’t got any virtual member functions. So even if int were a class, there would not be a plus over composition.

    So to say, virtual inheritance is the only real reason you’d need inheritance for anyway; everything else is just saving you masses of typing time. And I don’t think an int class/type with virtual members would be the smartest thing to imagine in the C++ world. At least not for you every day int.

    0 讨论(0)
  • 2020-12-02 18:39

    What others have said is true... int is a primitive in C++ (much like C#). However, you can achieve what you wanted by just building a class around int:

    class MyInt
    {
    private:
       int mInt;
    
    public:
       explicit MyInt(int in) { mInt = in; }
       // Getters/setters etc
    };
    

    You can then inherit from that all you jolly want.

    0 讨论(0)
  • 2020-12-02 18:40

    This is related to how the items are stored in memory. An int in C++ is an integral type, as mentioned elsewhere, and is just 32 or 64 bits (a word) in memory. An object, however, is stored differently in memory. It is usually stored on the heap, and it has functionality related to polymorphism.

    I don't know how to explain it any better. How would you inherit from the number 4?

    0 讨论(0)
  • 2020-12-02 18:42

    What does it mean to inherit from an int?

    "int" has no member functions; it has no member data, it's a 32 (or 64) bit representation in memory. It doesn't have it's own vtable. All what it "has" (it doesn't really even own them) are some operators like +-/* that are really more global functions than member functions.

    0 讨论(0)
  • 2020-12-02 18:43

    This answer is an implementation of UncleBens answer

    put in Primitive.hpp

    #pragma once
    
    template<typename T, typename Child>
    class Primitive {
    protected:
        T value;
    
    public:
    
        // we must type cast to child to so
        // a += 3 += 5 ... and etc.. work the same way
        // as on primitives
        Child &childRef(){
            return *((Child*)this);
        }
    
        // you can overload to give a default value if you want
        Primitive(){}
        explicit Primitive(T v):value(v){}
    
        T get(){
            return value;
        }
    
        #define OP(op) Child &operator op(Child const &v){\
            value op v.value; \
            return childRef(); \
        }
    
        // all with equals
        OP(+=)
        OP(-=)
        OP(*=)
        OP(/=)
        OP(<<=)
        OP(>>=)
        OP(|=)
        OP(^=)
        OP(&=)
        OP(%=)
    
        #undef OP
    
        #define OP(p) Child operator p(Child const &v){\
            Child other = childRef();\
            other p ## = v;\
            return other;\
        }
    
        OP(+)
        OP(-)
        OP(*)
        OP(/)
        OP(<<)
        OP(>>)
        OP(|)
        OP(^)
        OP(&)
        OP(%)
    
        #undef OP
    
    
        #define OP(p) bool operator p(Child const &v){\
            return value p v.value;\
        }
    
        OP(&&)
        OP(||)
        OP(<)
        OP(<=)
        OP(>)
        OP(>=)
        OP(==)
        OP(!=)
    
        #undef OP
    
        Child operator +(){return Child(value);}
        Child operator -(){return Child(-value);}
        Child &operator ++(){++value; return childRef();}
        Child operator ++(int){
            Child ret(value);
            ++value;
            return childRef();
        }
        Child operator --(int){
            Child ret(value);
            --value;
            return childRef();
        }
    
        bool operator!(){return !value;}
        Child operator~(){return Child(~value);}
    
    };
    

    Example:

    #include "Primitive.hpp"
    #include <iostream>
    
    using namespace std;
    class Integer : public Primitive<int, Integer> {
    public:
        Integer(){}
        Integer(int a):Primitive<int, Integer>(a) {}
    
    };
    int main(){
        Integer a(3);
        Integer b(8);
    
        a += b;
        cout << a.get() << "\n";
        Integer c;
    
        c = a + b;
        cout << c.get() << "\n";
    
        cout << (a > b) << "\n";
        cout << (!b) << " " << (!!b) << "\n";
    
    }
    
    0 讨论(0)
提交回复
热议问题