Alexandru Andrei
Alexandru Andrei

Reputation: 41

About const combined with reference and virtual inheritance

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

Answers (5)

taocp
taocp

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

Xaqq
Xaqq

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

David G
David G

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

blue
blue

Reputation: 2793

const int& f() const is the way.

You're right, 3 times for both.

Upvotes: 0

Matt Houser
Matt Houser

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

Related Questions