Idiomatic way to prevent slicing?

后端 未结 3 2057
执笔经年
执笔经年 2021-02-07 07:09

Sometimes it can be an annoyance that c++ defaults to allow slicing. For example

struct foo { int a; };
struct bar : foo { int b; };

int main() {
    bar x{1,2         


        
3条回答
  •  别那么骄傲
    2021-02-07 07:36

    Since 2011, the idiomatic way has been to use auto:

    #include 
    struct foo { int a; };
    struct bar : foo { int b; };
    
    int main() {
        bar x{1,2};
        auto y = x; // <- y is a bar
    }
    

    If you wish to actively prevent slicing, there are a number of ways:

    Usually the most preferable way, unless you specifically need inheritance (you often don't) is to use encapsulation:

    #include 
    
    struct foo { int a; };
    struct bar 
    { 
        bar(int a, int b)
        : foo_(a)
        , b(b)
        {}
    
        int b; 
    
        int get_a() const { return foo_.a; }
    
    private:
        foo foo_;
    };
    
    int main() {
        bar x{1,2};
    //    foo y = x; // <- does not compile
    
    }
    

    Another more specialised way might be to alter the permissions around copy operators:

    #include 
    
    struct foo { 
        int a; 
    protected:
        foo(foo const&) = default;
        foo(foo&&) = default;
        foo& operator=(foo const&) = default;
        foo& operator=(foo&&) = default;
    
    };
    
    struct bar : foo
    { 
        bar(int a, int b) 
        : foo{a}, b{b}
        {}
    
        int b; 
    };
    
    int main() {
        auto x  = bar (1,2);
    //    foo y = x; // <- does not compile
    }
    

提交回复
热议问题