This question already has an answer here:
Does attribute specifier sequence inherit?
(1 answer)
Closed 4 years ago.
I think it's not really a duplicate of Are function attributes inherited?, because I'm wondering about classes, not member functions :
struct [[nodiscard]] error {};
struct critical_error : error {};
critical_error foo();
int main() {
foo(); // no warning.
}
It seems that the [[nodiscard]] attribute is not inherited here. Is it the same for all type-attributes?
They aren't, as you asserted yourself. The standard is explicit in what exactly is inherited from a base class to a derived one:
10.6 Derived classes [class.derived]
2 [...] Unless redeclared in the derived class, members of a base class are also considered to be members of the derived class.
Members of a base class other than constructors are said to be inherited by the derived class.
Constructors of a base class can also be inherited as described in [namespace.udecl].
Inherited members can be referred to in expressions in the same manner as other members of the derived class, unless their names are hidden or ambiguous ([class.member.lookup]).
For the sake of completeness: There is also no wording about inheritance in the specific section about attributes.
Basically: an attribute is not a member of the class or a constructor, so it can't be inherited.
Related
This question already has answers here:
Constructor nominated by using declaration
(1 answer)
Using-declaration for base class constructors
(1 answer)
Closed 3 months ago.
I created an exception like this in my header_file run.h
struct invalid_assignment : std::runtime_error {
using std::runtime_error::runtime_error;
};
I dont understand the using std::runtime_error::runtime_error; part.
This looks unecessary.
From the C++ 17 Standard (10.3.3 The using declaration)
3 In a using-declaration used as a member-declaration, each
using-declarator’s nested-name-specifier shall name a base class of
the class being defined. If a using-declarator names a constructor,
its nested-name-specifier shall name a direct base class of the class
being defined.
and
16 For the purpose of overload resolution, the functions that are
introduced by a using-declaration into a derived class are treated as
though they were members of the derived class. In particular, the
implicit this parameter shall be treated as if it were a pointer to
the derived class rather than to the base class. This has no effect on
the type of the function, and in all other respects the function
remains a member of the base class. Likewise, constructors that are
introduced by a using-declaration are treated as though they were
constructors of the derived class when looking up the constructors of
the derived class (6.4.3.1) or forming a set of overload candidates
(16.3.1.3, 16.3.1.4, 16.3.1.7). If such a constructor is selected to
perform the initialization of an object of class type, all subobjects
other than the base class from which the constructor originated are
implicitly initialized (15.6.3).
Thus this using declaration
using std::runtime_error::runtime_error;
introduces constructors of the class std::runtime_error in the class invalid_assignment as if they are constructors of the class invalid_assignment.
This question already has an answer here:
C++11 inheriting constructors and access modifiers
(1 answer)
Closed 3 years ago.
When I use using like this why is the constructor inherited publicly?
class Base {
int x;
public:
Base(int x);
};
class Derived : public Base {
using Base::Base;
};
I can now do:
Derived d (2);
I thought that using declarations had the visibility of where they are situated. Here, it should be private.
From The C++ Programming Language:
A name brought into a derived
class scope by a using-declaration has its access determined by the placement of the using-declaration;
According to the C++17 Standard (10.3.3 The using declaration)
19 A synonym created by a using-declaration has the usual
accessibility for a member-declaration. A using-declarator that names a
constructor does not create a synonym; instead, the additional
constructors are accessible if they would be accessible when used to
construct an object of the corresponding base class, and the
accessibility of the using-declaration is ignored.
This question already has answers here:
What are the differences between struct and class in C++?
(30 answers)
Closed 7 years ago.
I read that the main difference between a class and a structure is that class is reference type and structure is value type.
can anybody explain me what does the value type and reference type means...?
You must be thinking of a different language. In C++, class types are semantically the same whether you introduce them with the class or struct keyword. They are object types (which one might loosely call "value types"), in the sense of being objects with a value representation.
The only difference is that base classes and members are public by default if you use struct, and private if you use class.
Reference types are denoted with & or &&, and can refer to any object or function type, not just classes.
The only difference between classes and structs is that by default members/bases are private to a class but public to a struct.
Now values and references are totally orthogonal concepts in C++ to class/struct, basically meaning instance of a class/struct and handle-to-instance.
In c++, the only differences between a struct and a class is the default member access and default inheritance:
struct A : BaseClassOrStruct { // public inheritance
int member; // public member
}
class A : BaseClassOrStruct { // private inheritance
int member; // private member
}
However, I usually do make a distinction between them: I use a struct to indicate that my objects really are just a collection of data members (that typically have public access) without methods (other than setters and getters).
This question already has answers here:
What are the differences between struct and class in C++?
(30 answers)
Closed 8 years ago.
I'm looking at some legacy code that looks like it was converted over from C to C++ and there are various classes that have public member variables and nothing else:
class sampleClass
public:
int fd;
customType clientHandle;
customType serverHandle;
};
From my understanding struct = class with no functions and public members so is this virtually exactly the same as a struct for practical reasons?
What happens when the code is compiled. Is it compiled down to the exact same "stuff" or do they get compiled differently
It is entirely the same, yes. The only two ways in which structs and classes differ are the default protection of members, and the default inheritance type of base classes.
In C++ only the default accessing differs between struct (public) and class (private).
Difference in struct and class and that is by default members of struct are public, while by default members of class are private.
Even while inheriting from struct, default specifier is public, while for class its private.
You can see my video tutorial on this.
This question already has answers here:
How can I initialize base class member variables in derived class constructor?
(7 answers)
Closed 4 years ago.
I have a mistake I cannot understand when initializing member data in an inherited class with two different methods I thought they should be theoretically identical.
class gSolObject
{
public:
gSolObject();
virtual ~gSolObject(){}
bool isCollisionObject;
};
class gPlanetObject : public gSolObject
{
public:
gPlanetObject();
~gPlanetObject(){};
};
gSolObject::gSolObject():isCollisionObject(1)
{
}
gPlanetObject::gPlanetObject():gSolObject(),isCollisionObject(0)
{
}
I get an error class 'gPlanetObject' does not have any field named 'isCollisionObject'.
However when I put the initialization right into the constructor's brackts {..} instead:
gPlanetObject::gPlanetObject():gSolObject()
{
isCollisionObject=0;
}
It compiles fine. Why would that be?
EDIT: This also does not work
gPlanetObject::gPlanetObject():gSolObject(),gSolObject::isCollisionObject(0)
It writes 'expected class-name before '(' token'
You can't initialize member variables declared in base classes, because the base class constructor has already initialized them. All base constructors execute before member constructors.
You can reassign it. Or you can call a base class constructor that takes an argument and initializes its members with that value.
Edited : You can't call a method of a uninitialized object (here gSolObject) and that's why it works when you execute isCollisionObject(0) in the constructor. Furthermore, if you always set it to 0, then you should use default value in the gSolObject constructor.