2015-07-11 73 views
3

我试图为变量值编写接口。基类仅提供一个enum字段,其​​中存储变量的类型(如int,char等)和一些虚拟函数。 继承此接口的类应该分别实现变量类型的表示。参考和指向接口的指针之间的C++不同行为

#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; 
    } 
}; 

然后我试图这样:

Var* np = new IntVar(1); 

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

输出是

0(类型:: INT),1,1(类型:: CHAR),一个

所以一切都按预期工作,但是当我用相同的参考文献尝试时,结果有点奇怪。

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

在这里,产量

0(类型:: INT),1,1(类型:: CHAR)和

为什么代码工作,何时使用指针并且不能与引用一起工作?或者我忽略了一些明显的错误?

+0

您正在使用'new'错误。你的程序有内存泄漏。 – celticminstrel

回答

4

使用指针的解决方案使nr首先指向IntVar,然后指向CharVar

使用引用的解决方案创建一个IntVar对象,然后为该对象创建一个新名称(nr),然后基于CharVar的值更改此对象的值。

引用不能像指针那样重新设置。引用在整个生命周期中引用同一个对象。

+0

谢谢,很好的解释:) – churill

1

声明

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

是一个非常不同的含义的分配比

np = new CharVar('a'); 

12.8节:

的非隐式定义的复制/移动赋值运算符-union 类X执行其子对象的成员复制/移动分配。 首先指定X的直接基类,按其在基指定符列表中的 声明的顺序,然后按照它们的 声明的顺序分配X的非静态数据成员的即时 在类定义....

NR使用隐式赋值运算符Var::operator=()从瓦尔那份领域。您没有更改引用类型,它仍然是对IntVar对象的引用。

1
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