I am looking at the implementation of an API that I am using.
I noticed that a struct is inheriting from a class and I paused to ponder on it...
First, I didn't see in the C++ manual I studied with that a struct could inherit from another struct:
struct A {};
struct B : public A {};
I guess that in such a case, struct B inherits from all the data in stuct A. Can we declare public/private members in a struct?
But I noticed this:
class A {};
struct B : public A {};
From my online C++ manual:
A class is an expanded concept of a data structure: instead of holding only data, it can hold both data and functions.
Is the above inheritance valid even if class A has some member functions? What happen to the functions when a struct inherit them? And what about the reverse: a class inheriting from a struct?
Practically speaking, I have this:
struct user_messages {
std::list<std::string> messages;
};
And I used to iterate over it like this foreach message in user_messages.messages
.
If I want to add member functions to my struct, can I change its declaration and "promote" it to a class, add functions, and still iterate over my user_messages.messages as I did before?
Obviously, I am still a newbie and I am still unclear how structs and classes interact with each other, what's the practical difference betwe开发者_运维问答en the two, and what the inheritance rules are...
Yes, struct can inherit from class in C++.
In C++, classes and struct are the same except for their default behaviour with regards to inheritance and access levels of members.
C++ class
- Default Inheritance = private
- Default Access Level for Member Variables and Functions = private
C++ struct
- Default Inheritance = public
- Default Access Level for Member Variables and Functions = public
In C++
struct A { /* some fields/methods ... */ };
is equivalent to:
class A { public: /* some fields/methods ... */ };
And
class A { /* some fields/methods ... */ };
is equivalent to:
struct A { private: /* some fields/methods ... */ };
That means that the members of a struct/class are by default public/private.
Using struct
also changes the default inheritance to public
, i.e.
struct A { }; // or: class A { };
class B : A { };
is equivalent to
struct A { }; // or: class A { };
struct B : private A { };
And the other way around, this
struct A { }; // or: class A { };
struct B : A { };
is equivalent to:
struct A { }; // or: class A { };
class B : public A { };
Summary: Yes, a struct
can inherit from a class. The difference between the class
and struct
keywords is just a change in the default private/public specifiers.
The only difference between a struct and a class is the default access level for members (private for classes, public for structs). This means that a struct should be able to inherit from a class, and vice-versa.
However, there is usually a difference in how structs and classes are used that is not mandated by the standard. structs are often used for pure data, ( or objects without polymorphism depending on your projects preference) and classes are used for the other cases. I emphasise that this is just a stylistic difference and not required.
The main thing to understand is that structs come from C, whereas classes are C++. This means that although structs ARE first-class object-orientated citizens, they also have a legacy purpose, which is the reason for classes being separate and structs being default-access public. However, once this is done with, they're absolutely and totally identical and interchangable in every way.
A struct is the same thing as a class except that a class defaults its members to private while a struct defaults its members to public. As a result, yes, you can inherit between the two. See in C++, can I derive a class from a struct.
struct and class are pretty much interchangeable - just with different defaults in that classes default to private inheritance and members, structs to public. The class keyword (and not struct) must be used for eg. "template <class T>".
That said, many programmers use the two to give a slight suggestion to a programmer reading the code: by using a struct you're subtly suggesting a less encapsulating, OO design. A struct might be used internal to a library - where getting at the guts of it all is fair game, whereas classes are used on the boundary where API changes would inconvenience clients and better abstraction is useful. This very loose convention has grown out of the difference in default accessibility - lazy/efficient/concise (take your pick) programmers do what's easiest unless there's a benefit otherwise, and not typing access specifiers is nice when possible.
Yes a struct
can inherit from a class. struct
and class
differ only in the access-specifier assumed for the members and for a base classes (or structs) if not specified explicitly in C++ . For structs it's public
. For classes it's private
.
The sentence you quote from the manual is about the concept of a class in C++, as compared to the concept of a data structure in C. In C++ new keyword - class
was introduced to better reflect the change in the concept, but for compatibility with code in C, an old keyword struct
was left and it's meaning is as described above.
Yes. Struct can inherit from a class and vice versa. The accessibility rule is
$11.2/2- "In the absence of an access-specifier for a base class, public is assumed when the derived class is declared struct and private is assumed when the class is declared class."
EDIT 2: So you can change your class as:. Note that it is a bad idea to have public data members usually.
class user_messages { // i also changed the name when OP was modified :)
public:
std::list<std::string> messages;
};
A class will not publicly inherit from a struct. A struct will publicly inherit from a class or a struct.
class A
{
public:
int a;
};
struct B : A
{};
B b; b.a=5; //OK. a is accessible
class A
{
public:
int a;
};
struct B : public A
{};
It means the same. B b; b.a=5; //OK. a is accessible
struct A
{int a;};
class B : A
{};
B b; b.a=5; //NOT OK. a is NOT accessible
struct A
{int a;};
class B : public A
{};
B b; b.a=5; //OK. a is accessible
Finally:
class A
{int a;};
class B : A
{};
B b; b.a=5; //NOT OK. a is NOT accessible
class A
{int a;};
class B : public A
{};
B b; b.a=5; //NOT OK. a is NOT accessible
精彩评论