C ++ different behavior between reference and interface pointer

I was trying to write an interface for a variable value. The base class provides the only field enum

where the type of the variable is stored (eg int

, char

etc.)) and some virtual functions. Classes inheriting this interface must implement a variable type representation each.

#include <iostream>

enum Type
{
    INT, CHAR
};

class Var
{
    Type type;
public:
    Var(Type t):
        type(t)
    {}
    virtual void printValue()
    {
        std::cout << "-\n";
    }
    virtual void printType()
    {
        std::cout << type << std::endl;
    }
};

class IntVar : public Var
{
    int value;
public:
    IntVar(int i):
        Var(INT),
        value(i)
    {}
    void printValue()
    {
        std::cout << value << std::endl;
    }
};

class CharVar : public Var
{
    char value;
public:
    CharVar(char c):
        Var(CHAR),
        value(c)
    {}
    void printValue()
    {
        std::cout << value << std::endl;
    }
};

      

Then I tried this:

Var* np = new IntVar(1);

np->printType();
np->printValue();
np = new CharVar('a');
np->printType();
np->printValue();

      

The way out was

0 (Type :: INT), 1, 1 (Type :: CHAR), a

so everything worked as expected, but when I tried the same thing with links, the result was a little strange.

Var& nr = *(new IntVar(1));
nr.printType();
nr.printValue();
nr = *(new CharVar('a'));
nr.printType();
nr.printValue();

      

Here the output was

0 (Type :: INT), 1, 1 (Type :: CHAR) and 1

Why was the code working when using pointers and not working with links? Or am I missing some obvious mistakes?

+3


source to share


3 answers


The decision using pointers is done nr

first to IntVar

, and then to CharVar

.

The reference solution creates an object IntVar

, then creates a new name ( nr

) for that object , and then changes the values โ€‹โ€‹of this object based on the values CharVar

.



Links cannot be reinstalled as you did with pointers. The link refers to the same object throughout its life.

+4


source


Statement

nr = *(new CharVar('a'));

      

is an assignment with a completely different meaning than

np = new CharVar('a');

      



Section 12.8:

The implicitly defined copy / move assignment operator for a non-single class X performs incremental copy / move assignment of its subobjects. Direct base classes X are assigned first, in the order in which they are declared in the base-specifier list, and then the immediate non-static X data members are assigned in the order in which they were declared in the class definition ....

nr uses an implicit assignment operator Var::operator=()

that copies fields from Var. You are not changing the reference type, it is still a reference to the IntVar object.

+1


source


Var& nr = *(new IntVar(1));  //nr are Bound to IntVar object
nr=*(new CharVar('a'));    //replace the base part of IntVar object
                            //  by the base part of CharVar object

      

+1


source







All Articles