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.
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:
Questions about template and typename [duplicate]
(1 answer)
Closed 5 months ago.
I read this article but I don't understand the meaning of this part of the code:
template <typename T> struct counted : T, private instance_counter<T>
{
using T::T;
};
It must be something simple as "make visible all names from namespace" but I don't completely understand it.
T is the base class.
T::T is/are the constructor(s) of the base class T. A constructor has the same name as the class being constructed.
using T::T; brings the constructor(s) of the base class into the current scope, which is the derived class counted.
This line allows counted to be constructed using any constructor that T allows.
make visible all names from namespace
No, because T isn't a namespace. You can't derive from a namespace.
The using keyword has more than one meaning.
You're thinking of the using directive for namespaces, but the using declaration works for both namespace members (at namespace scope) and class members (inside a class). Since we already established T is not a namespace, this is obviously the second case.
Inside a class using T::member would normally just prevent base-class names being hidden by the derived class, but T::T means the base class constructor, which as a special case inherits constructors from T.
template <typename T> struct counted : T
{
using T::T; // now counted<T> can directly use any of T's constructors
};
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.
This question already has answers here:
Why does decltype not see the member declaration? [duplicate]
(3 answers)
Closed 5 years ago.
Why this code is incorrect?
class Method
{
public:
Method(decltype(info2) info1);
virtual ~Method(){}
protected:
QSharedPointer<info> info2;
};
But this code is correct:
class Method
{
public:
virtual ~Method(){}
protected:
QSharedPointer<info> info2;
public:
Method(decltype(info2) info1);
};
why place of class constructor is important?
I thought that place of definition class constructor isnt important.
I believe this part of the standard is relevant [basic.scope.class]/1.1:
The potential scope of a name declared in a class consists not only of the declarative region following the
name’s point of declaration, but also of all function bodies, default arguments,
exception-specification
s,
and
brace-or-equal-initializers
of non-static data members in that class (including such things in nested
classes).
Note that it only mentions default arguments. So this works since the decltype is referred in a default argument:
Method(QSharedPointer<int> info1 = decltype(info2)())
And this also works since it's inside a body:
Method(<...>)
{
decltype(info2) info3;
}
However your example does not work because such a placement of a decltype is not covered by the paragraph I quoted, thus the name info2 is considered out of scope.
Place of QSharedPointer info2;
is important.
'info2' should be defined before using it into decltype (http://en.cppreference.com/w/cpp/language/decltype).
Next would not work either:
void f() {
d();
}
void d() {
}
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.