Reputation: 41
I have the following code:
class A
{
int x;
public:
A(int i=25) { x=i; }
int& f() const { return x; }
};
int main()
{
A a(15);
cout<<a.f();
return 0;
}
I get an error saying that I can't initialize a reference of type int& from an expression of type const int? If I modify function's f() header, like "int f() const" or like "int& f()" it works. I know that a const function can't modify the members of the class, but in my example that's not happening and still is something wrong I can't understand.
Secondly, I have this piece of code:
class B { /* instructions */ };
class D1: virtual B { /* instructions */ };
class D2: virtual B { /* instructions */ };
class D3: B { /* instructions */ };
class D4: private B { /* instructions */ };
class D5: virtual public B { /* instructions */ };
class M1: D1, public D2, D3, private D4, virtual D5
{ /* instructions */ };
class M2: D1, D2, virtual D3, virtual D4, virtual D5
{ /* instructions */ };
The question is how many times is B inherited in M1 and and in M2. I think the answer is 3 (first from D1, then from D3 and then from D4) for both, but I'm not sure. Am I right?
Upvotes: 1
Views: 265
Reputation: 23624
For your first question:
class A
{
int x;
public:
A(int i=25) { x=i; }
const int& f() const { return x; }
//^^You should add const here
};
int main()
{
A a(15);
cout<<a.f();
return 0;
}
Otherwise, you are returning non-const reference from a const member function. Another option is to simply return by value.
Upvotes: 1
Reputation: 4386
You're returning a reference to a member of your class. However, since you method is const, you're not allowed to return a non-const reference, because this would allow for the end user to modify your class state, after calling a const method.
Consider this:
class A
{
int x;
public:
A(int i=25) { x=i; }
const int& f() const { return x; }
};
int main()
{
A a(15);
int &ref = const_cast<int &>(a.f());
ref = 42;
// a.x == 42
return 0;
}
Using const_cast
is generally a bad idea, it's here to demonstrate what could happen if you were allowed to return a non-const reference from a const method.
The end user could change the property x
from your class, because of a call to a const function, which is not supposed to happen.
Returning the result by value is imo the way to go, since it's just an integer.
Upvotes: 3
Reputation: 96800
In a non-static const
member function, the type of this
is changed to A const *const
. Therefore it follows that the type of x
is changed to int const&
. A const
object cannot be implicitly-converted to a non-const version of its type.
Upvotes: 1
Reputation: 36073
First, your function may not be modifying a const value, but you're trying to return a const value as a non-const, which could then be modified. The compiler is protecting you. To keep it const, modify it as:
const int &f() const {... }
or
int f() const { .... }
The first returns a const reference, the second returns the result by-value.
Upvotes: 2