Is it possible to subclass a C struct in C++ and use pointers to the struct in C code?

后端 未结 10 1011
滥情空心
滥情空心 2021-02-07 00:10

Is there a side effect in doing this:

C code:

struct foo {
      int k;
};

int ret_foo(const struct foo* f){ 
    return f.k; 
}

C++ c

相关标签:
10条回答
  • 2021-02-07 00:53

    I don't get why you don't simply make ret_foo a member method. Your current way makes your code awfully hard to understand. What is so difficult about using a real class in the first place with a member variable and get/set methods?

    I know it's possible to subclass structs in C++, but the danger is that others won't be able to understand what you coded because it's so seldom that somebody actually does it. I'd go for a robust and common solution instead.

    0 讨论(0)
  • 2021-02-07 00:57

    Wow, that's evil.

    Is this portable across compilers?

    Most definitely not. Consider the following:

    foo* x = new bar();
    delete x;
    

    In order for this to work, foo's destructor must be virtual which it clearly isn't. As long as you don't use new and as long as the derived objectd don't have custom destructors, though, you could be lucky.

    /EDIT: On the other hand, if the code is only used as in the question, inheritance has no advantage over composition. Just follow the advice given by m_pGladiator.

    0 讨论(0)
  • 2021-02-07 01:02

    It probably will work but I do not believe it is guaranteed to. The following is a quote from ISO C++ 10/5:

    A base class subobject might have a layout (3.7) different from the layout of a most derived object of the same type.

    It's hard to see how in the "real world" this could actually be the case.

    EDIT:

    The bottom line is that the standard has not limited the number of places where a base class subobject layout can be different from a concrete object with that same Base type. The result is that any assumptions you may have, such as POD-ness etc. are not necessarily true for the base class subobject.

    EDIT:

    An alternative approach, and one whose behaviour is well defined is to make 'foo' a member of 'bar' and to provide a conversion operator where it's necessary.

    class bar {
    public:    
       int my_bar() { 
           return ret_foo( foo_ ); 
       }
    
       // 
       // This allows a 'bar' to be used where a 'foo' is expected
       inline operator foo& () {
         return foo_;
       }
    
    private:    
      foo foo_;
    };
    
    0 讨论(0)
  • 2021-02-07 01:03

    I don't think it is necessarily a problem. The behaviour is well defined, and as long as you are careful with life-time issues (don't mix and match allocations between the C++ and C code) will do what you want. It should be perfectly portable across compilers.

    The problem with destructors is real, but applies any time the base class destructor isn't virtual not just for C structs. It is something you need to be aware of but doesn't preclude using this pattern.

    0 讨论(0)
提交回复
热议问题