Here's some contrived example code:
template<typename T> void Do(T arg) { (void)arg->b; }
namespace A {
struct Foo { int a; };
}
namespace B {
struct Foo { int b; };
struct Bar : A::Foo {
void Blah() { Do((Foo *)0); }
};
}
Which when compiled with gcc 4.8.2 (clang gives a similar error):
namespacebug.cpp: In instantiation of ‘void Do(T) [with T = A::Foo*]’:
namespacebug.cpp:10:34: required from here
namespacebug.cpp:1:39: error: ‘struct A::Foo’ has no member named ‘b’
template<typename T> void Do(T arg) { (void)arg->b; }
^
Note in the error it refers to T = A::Foo
even though at the call-site I am creating a Foo
within namespace B
. If I remove the base class decl (: A::Foo
) then all compiles fine.
This appears to suggest that inheriting from A::Foo
somehow brings it into my namespace and matches it to my use of Foo
? What C++ "feature" causes this?
(Of course, this issue can easily be fixed by namespacing my use of Foo
, but that's not the question.)
Inheritance allows us to define a class that inherits all the methods and properties from another class. Parent class is the class being inherited from, also called base class. Child class is the class that inherits from another class, also called derived class.
yes you can inheritance and namespaces are completely separate concepts. Inheritance lets you derive a child class from any none sealed object. A namespace is simply a conceptual container for logically locating and grouping code. Save this answer.
In C#, inheritance allows us to create a new class from an existing class. It is a key feature of Object-Oriented Programming (OOP). The derived class inherits the fields and methods of the base class. This helps with the code reusability in C#.
Classes are data types. They are an expanded concept of structures, they can contain data members, but they can also contain functions as members whereas a namespace is simply an abstract way of grouping items together. A namespace cannot be created as an object; think of it more as a naming convention.
Because of the injected-class-name rule, the name of a class is visible as though it were a member.
9/2
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name.
So it is as though class A::Foo
contains a member Foo
which names the type A::Foo
. Since name lookup in Bar::Blah()
considers base members of Bar
before namespace members, the name lookup for Foo
finds the injected-class-name, which names A::Foo
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With