Understanding scope with inheritance in C++ - c++

I'm testing my understanding of inheritance in C++ and was reading through some example code. Based on the program output, it seems to me that the double add() and int add() functions have different scope, and instead of calling the double add() function with argument 10.5, there is an implicit type conversion from double to int (which is always truncated) and the function int add() is called instead. The type conversion would explain why the output is 11 11.
My questions are as follows:
What is the scope of inherited functions that are overloaded?
When, if ever, is a type conversion from double to int invalid (i.e. would instead result in a compile-time error)?
Where can I read more about the nuances of namespaces/scope with inheritance in C++?
#include <iostream>
using namespace std;
class One {
public:
double add(double x) { return x + 0.1; }
};
class Two : public One {
public:
int add(int x) { return x + 1; }
};
int main(int argc, char *argv[]) {
Two obj;
cout << obj.add(10) << " " << obj.add(10.5) << endl;
return 0;
}

The declaration of add as int add(int x) { return x + 1; } hides any other definitions of add from outer scopes, this is the same behaviour as shadowing of variables in nested blocks in a function.
Name lookup always finds a name in a scope before going on to potential overload resolution amongst multiple occurrences of that name in the same scope; obj.add(10.5) finds Two::add() and so does not go on to check outer scopes.
You can redeclare the functions from outer scopes in Two with using One::add;
On the conversion topic; a double argument always matches an int parameter. It can be invalid if the double is out of range for int but that is runtime undefined behaviour (no diagnostic required).
This topic is covered in C++ FAQ , you could also check the Name Lookup article on cppreference.

Overloading does not work with inheritance in C++:
Overloading doesn’t work for derived class in C++ programming
language. There is no overload resolution between Base and Derived.
The compiler looks into the scope of Derived, finds the single
function “double f(double)” and calls it. It never disturbs with the
(enclosing) scope of Base. In C++, there is no overloading across
scopes – derived class scopes are not an exception to this general
rule
The example they used had double f(double) in the derived class.
https://www.geeksforgeeks.org/does-overloading-work-with-inheritance/
To fix this, the class would have to be redesigned. I can't give any specific feedback as to how to change it as the class is very generic.

In addition to the answers above, I would like to add that you can avoid this issue of overloading by creating a template for One::add() which will allow it to accept both integers and doubles, and then let class Two inherite it.
#include <iostream>
using namespace std;
class One {
public:
template <typename T> //Template allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type.
double add(T x)
{
if (floor(x) == x) //Check if x is integer
return x + 1;
else
{
return x + 0.1;
}
}
};
class Two : public One {
public:
//No need for overloading add() here because in Class One, add() function will accept integers and doubles
};
int main(int argc, char* argv[]) {
Two obj;
cout << obj.add(10) << " " << obj.add(10.5) << endl;
return 0;
}

Related

C++: why can a function declaration not assign a name to it's argument(s)? [duplicate]

The following is a perfectly legal C++ code
void foo (int) {
cout << "Yo!" << endl;
}
int main (int argc, char const *argv[]) {
foo(5);
return 0;
}
I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.
Why is this legal to begin with?
Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.
The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).
There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.
Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.
This may happen for example for a method in a derived class, for a callback function or for a template parameter.
Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.
Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".
It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.
It's used like this:
class Friendly; // Just a forward declaration
class Key {
private:
Key() {}
friend class Friendly;
};
class Safe() {
public:
static int locked(Key, int i) {
// Do something with `i`,
// but the key is never used.
return i;
}
private:
static void inaccessible() {}
};
class Friendly {
public:
void foo() {
int i = Safe::locked(Key(), 1); // OK
int j = Safe::locked({}, 2); // OK, sice C++11
}
void bar() {
Safe::inaccessible(); // Not OK, its inaccessible
}
};
int i = Safe::locked(3); // Not OK, wrong parameters
int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly
I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.
// named-reference.cpp
// Compile with: /EHsc
#include <iostream>
using namespace std;
// A class that contains a memory resource.
class MemoryBlock
{
// TODO: Add resources for the class here.
};
void g(const MemoryBlock&)
{
cout << "In g(const MemoryBlock&)." << endl;
}
void g(MemoryBlock&&)
{
cout << "In g(MemoryBlock&&)." << endl;
}
MemoryBlock&& f(MemoryBlock&& block)
{
g(block);
return block;
}
int main()
{
g(f(MemoryBlock()));
}
This example produces the following output:
In g(const MemoryBlock&).
In g(MemoryBlock&&).
In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).

what is the significance of unnamed argument list while defining function in c++ [duplicate]

The following is a perfectly legal C++ code
void foo (int) {
cout << "Yo!" << endl;
}
int main (int argc, char const *argv[]) {
foo(5);
return 0;
}
I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.
Why is this legal to begin with?
Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.
The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).
There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.
Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.
This may happen for example for a method in a derived class, for a callback function or for a template parameter.
Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.
Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".
It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.
It's used like this:
class Friendly; // Just a forward declaration
class Key {
private:
Key() {}
friend class Friendly;
};
class Safe() {
public:
static int locked(Key, int i) {
// Do something with `i`,
// but the key is never used.
return i;
}
private:
static void inaccessible() {}
};
class Friendly {
public:
void foo() {
int i = Safe::locked(Key(), 1); // OK
int j = Safe::locked({}, 2); // OK, sice C++11
}
void bar() {
Safe::inaccessible(); // Not OK, its inaccessible
}
};
int i = Safe::locked(3); // Not OK, wrong parameters
int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly
I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.
// named-reference.cpp
// Compile with: /EHsc
#include <iostream>
using namespace std;
// A class that contains a memory resource.
class MemoryBlock
{
// TODO: Add resources for the class here.
};
void g(const MemoryBlock&)
{
cout << "In g(const MemoryBlock&)." << endl;
}
void g(MemoryBlock&&)
{
cout << "In g(MemoryBlock&&)." << endl;
}
MemoryBlock&& f(MemoryBlock&& block)
{
g(block);
return block;
}
int main()
{
g(f(MemoryBlock()));
}
This example produces the following output:
In g(const MemoryBlock&).
In g(MemoryBlock&&).
In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).

Accessing members from an object itself with either THIS or member scope

What is the proper way of accessing a member data/function that is part of the method's class? There appears to be 3 means:
class test{
private:
int variable;
public:
void setVariable(int value) {
variable = value; // method 1, using the variable name directly
this->variable = value; // method 2, via pointer dereference of 'this'
test::variable = value; // method 3, via scope operator
}
};
They all seems to work as far as I can tell. Are they equivalent? Is there a reason to use one over the other beside style/consistency?
In addition to style and consistency, as you mention, sometimes you have to use a specific syntax to disambiguate.
"method 2" can be used to disambiguate between local variables and class members.
"method 3" can be used to disambiguate between fields with the same name in different places of your class hierarchy.
In general it does not matter so the simpler options member = value; is preferred. In some cases there might be ambiguity with a local variable and there you can qualify with the this-> prefix, but a better approach would be avoid the ambiguity altogether.
There are however some corner cases where it does matter. When dealing with virtual functions, using a qualified name (type::member) disables runtime dispatch and ensures that the final overrider at the type level is called:
struct base {
virtual int f() { return 1; }
};
struct derived : base {
virtual int f() { return 2; }
void g() {
std::cout << f() << "\n";
std::cout << derived::f() << "\n";
}
};
struct mostderived : derived {
virtual int f() { return 3; }
};
int main() {
mostderived d;
d.g(); // 3 2
}
When dealing with template classes and inheritance, lookup is performed in two phases. During the first phase, non-dependent names have to be resolved. An unqualified name is a non-dependent name, so in some cases you need to qualify with either this-> or type::, and the distinction above still applies. The extra qualification serves to make the name dependent:
template <typename T>
struct derived : T {
void g() {
// std::cout << f() << "\n"; // Error, cannot resolve f() [*]
this->f(); // Ok, pick final overrider at runtime
derived::f(); // Ok, pick overrider here: base::f()
}
};
struct base {
virtual int f() { return 1; }
};
struct mostderived : derived<base> {
virtual int f() { return 3; }
};
int main() {
mostderived d;
d.g(); // 3, 1
}
For code inside the object, it generally makes no difference, so it's usually cleanest to just use variable = value; and be done with it.
Sometimes in a template, you can run into a situation where just using the variable name by itself is ambiguous, and this->variable removes that ambiguity -- but this is rare enough that I definitely would not use this->everything on a regular basis just because it might be useful once in a great while.
Method 1: This is the common way it is done.
Method 2: This is the best and most consistence way to do it. It makes it very clear to read and understand what's happening.
Method 3: I've never seen done in real world code.
As a side note: When using method 1 if there is a naming conflict with the function parameter and member variable the function parameter will be used over the member variable.
if we have:
void setVariable(int variable) {
variable = variable; // method 1, this does not change the member variable.
this->variable = variable; // method 2, via pointer dereference of 'this'
test::variable = variable; // method 3, via scope operator
}
The pointer this is often used for comparison in an overloaded operator of a class. One of its uses can be if the parameter passed in the function is the same as the object itself, for example:
class CDummy {
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (&param == this) return true;
else return false;
}
This is also used to return a pointer to the object itself
ClassEx ClassEx::Func(//params)
{
//code
return *this;
}
As for normal comparison, value instead of this->value will be more efficient to use, the use of this-> is ambiguous unless you're checking values.
There is no difference in performance. The :: is used to avoid ambiguities, such as when you have a local variable with same name of a field, or a base class that declares a field with same name of a field in a derived class. The -> is supported because the type of this is a pointer to object, so the compiler must accept this->something, and that can also be used to avoid ambiguities or just to let code more clear.
And to add to the above answers:
Some code styles like to identify member variables using a fixed prefix like _ or m. Using "method 2" is another (and imho much nicer way) of achieving this clarity in the code.
Prefering this->value over value is also a little like using std::cin instead cin with a using namespace std.
Use method 1
variable = value;
Saves you buying a new keyboard so frequently!
(Having said that I should stop stilling coffee over mine!)

Why does C++ allow unnamed function parameters?

The following is a perfectly legal C++ code
void foo (int) {
cout << "Yo!" << endl;
}
int main (int argc, char const *argv[]) {
foo(5);
return 0;
}
I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.
Why is this legal to begin with?
Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.
The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).
There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.
Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.
This may happen for example for a method in a derived class, for a callback function or for a template parameter.
Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.
Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".
It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.
It's used like this:
class Friendly; // Just a forward declaration
class Key {
private:
Key() {}
friend class Friendly;
};
class Safe() {
public:
static int locked(Key, int i) {
// Do something with `i`,
// but the key is never used.
return i;
}
private:
static void inaccessible() {}
};
class Friendly {
public:
void foo() {
int i = Safe::locked(Key(), 1); // OK
int j = Safe::locked({}, 2); // OK, sice C++11
}
void bar() {
Safe::inaccessible(); // Not OK, its inaccessible
}
};
int i = Safe::locked(3); // Not OK, wrong parameters
int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly
I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.
// named-reference.cpp
// Compile with: /EHsc
#include <iostream>
using namespace std;
// A class that contains a memory resource.
class MemoryBlock
{
// TODO: Add resources for the class here.
};
void g(const MemoryBlock&)
{
cout << "In g(const MemoryBlock&)." << endl;
}
void g(MemoryBlock&&)
{
cout << "In g(MemoryBlock&&)." << endl;
}
MemoryBlock&& f(MemoryBlock&& block)
{
g(block);
return block;
}
int main()
{
g(f(MemoryBlock()));
}
This example produces the following output:
In g(const MemoryBlock&).
In g(MemoryBlock&&).
In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).

Why does C++ need the scope resolution operator?

(I know what the scope resolution operator does, and how and when to use it.)
Why does C++ have the :: operator, instead of using the . operator for this purpose? Java doesn't have a separate operator, and works fine. Is there some difference between C++ and Java that means C++ requires a separate operator in order to be parsable?
My only guess is that :: is needed for precedence reasons, but I can't think why it needs to have higher precedence than, say, .. The only situation I can think it would is so that something like
a.b::c;
would be parsed as
a.(b::c);
, but I can't think of any situation in which syntax like this would be legal anyway.
Maybe it's just a case of "they do different things, so they might as well look different". But that doesn't explain why :: has higher precedence than ..
Because someone in the C++ standards committee thought that it was a good idea to allow this code to work:
struct foo
{
int blah;
};
struct thingy
{
int data;
};
struct bar : public foo
{
thingy foo;
};
int main()
{
bar test;
test.foo.data = 5;
test.foo::blah = 10;
return 0;
}
Basically, it allows a member variable and a derived class type to have the same name. I have no idea what someone was smoking when they thought that this was important. But there it is.
When the compiler sees ., it knows that the thing to the left must be an object. When it sees ::, it must be a typename or namespace (or nothing, indicating the global namespace). That's how it resolves this ambiguity.
Why C++ doesn't use . where it uses ::, is because this is how the language is defined. One plausible reason could be, to refer to the global namespace using the syntax ::a as shown below:
int a = 10;
namespace M
{
int a = 20;
namespace N
{
int a = 30;
void f()
{
int x = a; //a refers to the name inside N, same as M::N::a
int y = M::a; //M::a refers to the name inside M
int z = ::a; //::a refers to the name in the global namespace
std::cout<< x <<","<< y <<","<< z <<std::endl; //30,20,10
}
}
}
Online Demo
I don't know how Java solves this. I don't even know if in Java there is global namespace. In C#, you refer to global name using the syntax global::a, which means even C# has :: operator.
but I can't think of any situation in which syntax like this would be legal anyway.
Who said syntax like a.b::c is not legal?
Consider these classes:
struct A
{
void f() { std::cout << "A::f()" << std::endl; }
};
struct B : A
{
void f(int) { std::cout << "B::f(int)" << std::endl; }
};
Now see this (ideone):
B b;
b.f(10); //ok
b.f(); //error - as the function is hidden
b.f() cannot be called like that, as the function is hidden, and the GCC gives this error message:
error: no matching function for call to ‘B::f()’
In order to call b.f() (or rather A::f()), you need scope resolution operator:
b.A::f(); //ok - explicitly selecting the hidden function using scope resolution
Demo at ideone
Why does C++ have the :: operator, instead of using the . operator for this purpose?
The reason is given by Stroustrup himself:
In C with Classes, a dot was used to express membership of a class as well as expressing selection of a member of a particular object.
This had been the cause of some minor confusion and could also be used to construct ambiguous examples. To alleviate this, :: was introduced to mean membership of class and . was retained exclusively for membership of object
(Bjarne Stroustrup A History of C++: 1979−1991 page 21 - § 3.3.1)
Moreover it's true that
they do different things, so they might as well look different
indeed
In N::m neither N nor m are expressions with values; N and m are names known to the compiler and :: performs a (compile time) scope resolution rather than an expression evaluation. One could imagine allowing overloading of x::y where x is an object rather than a namespace or a class, but that would - contrary to first appearances - involve introducing new syntax (to allow expr::expr). It is not obvious what benefits such a complication would bring.
Operator . (dot) could in principle be overloaded using the same technique as used for ->.
(Bjarne Stroustrup's C++ Style and Technique FAQ)
Unlike Java, C++ has multiple inheritance. Here is one example where scope resolution of the kind you're talking about becomes important:
#include <iostream>
using namespace std;
struct a
{
int x;
};
struct b
{
int x;
};
struct c : public a, public b
{
::a a;
::b b;
};
int main() {
c v;
v.a::x = 5;
v.a.x = 55;
v.b::x = 6;
v.b.x = 66;
cout << v.a::x << " " << v.b::x << endl;
cout << v.a.x << " " << v.b.x << endl;
return 0;
}
Just to answer the final bit of the question about operator precedence:
class A {
public:
char A;
};
class B : public A {
public:
double A;
};
int main(int c, char** v)
{
B myB;
myB.A = 7.89;
myB.A::A = 'a';
// On the line above a hypothetical myB.A.A
// syntax would parse as (myB.A).A and since
// (myB.A) is of type double you get (double).A in the
// next step. Of course the '.' operator has no
// meaning for doubles so it causes a syntax error.
// For this reason a different operator that binds
// more strongly than '.' is needed.
return 0;
}
I always assumed C++ dot/:: usage was a style choice, to make code easier to read. As the OP writes "they do different things, so should look different."
Coming from C++, long ago, to C#, I found using only dots confusing. I was used to seeing A::doStuff(); B.doStuff();, and knowing the first is a regular function, in a namespace, and the second is a member function on instance B.
C++ is maybe my fifth language, after Basic, assembly, Pascal and Fortran, so I don't think it's first language syndrome, and I'm more a C# programmer now. But, IMHO, if you've used both, C++-style double-colon for namespaces reads better. I feel like Java/C# chose dots for both to (successfully) ease the front of the learning curve.
Scope resolution operator(::) is used to define a function outside a class or when we want to use a global variable but also has a local variable with same name.