C++ 引用和接口指针之间的不同行为
C++ different behavior between reference and pointer to interface
我正在尝试为变量值编写一个接口。基础class只提供了一个enum
字段,其中存储了变量的类型(如int
、char
等)和一些虚函数。
class继承这个接口的es应该各自实现一个变量类型的表示。
#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 (Type::INT), 1, 1 (Type::CHAR), a
所以一切都按预期进行,但是当我对引用进行相同的尝试时,结果有点奇怪。
Var& nr = *(new IntVar(1));
nr.printType();
nr.printValue();
nr = *(new CharVar('a'));
nr.printType();
nr.printValue();
这里的输出是
0 (Type::INT), 1, 1 (Type::CHAR) and 1
为什么代码在使用指针时有效,而在使用引用时却无效?还是我忽略了一些明显的错误?
声明
nr = *(new CharVar('a'));
是一个与
意义完全不同的赋值
np = new CharVar('a');
第 12.8 节:
The implicitly-defined copy/move assignment operator for a non-union
class X performs memberwise copy/move assignment of its subobjects.
The direct base classes of X are assigned first, in the order of their
declaration in the base-specifier-list, and then the immediate
non-static data members of X are assigned, in the order in which they
were declared in the class definition....
nr 正在使用从 Var 复制字段的隐式赋值运算符 Var::operator=()
。您没有更改引用类型,它仍然是对 IntVar 对象的引用。
使用指针的解决方案使nr
首先指向一个IntVar
,然后指向一个CharVar
。
使用引用的解决方案创建一个 IntVar
对象,然后为该对象创建一个新名称 (nr
),然后根据 [=] 的值更改该对象的值12=].
不能像对指针那样对引用进行变基。引用在其整个生命周期中引用同一个对象。
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
我正在尝试为变量值编写一个接口。基础class只提供了一个enum
字段,其中存储了变量的类型(如int
、char
等)和一些虚函数。
class继承这个接口的es应该各自实现一个变量类型的表示。
#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 (Type::INT), 1, 1 (Type::CHAR), a
所以一切都按预期进行,但是当我对引用进行相同的尝试时,结果有点奇怪。
Var& nr = *(new IntVar(1));
nr.printType();
nr.printValue();
nr = *(new CharVar('a'));
nr.printType();
nr.printValue();
这里的输出是
0 (Type::INT), 1, 1 (Type::CHAR) and 1
为什么代码在使用指针时有效,而在使用引用时却无效?还是我忽略了一些明显的错误?
声明
nr = *(new CharVar('a'));
是一个与
意义完全不同的赋值np = new CharVar('a');
第 12.8 节:
The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy/move assignment of its subobjects. The direct base classes of X are assigned first, in the order of their declaration in the base-specifier-list, and then the immediate non-static data members of X are assigned, in the order in which they were declared in the class definition....
nr 正在使用从 Var 复制字段的隐式赋值运算符 Var::operator=()
。您没有更改引用类型,它仍然是对 IntVar 对象的引用。
使用指针的解决方案使nr
首先指向一个IntVar
,然后指向一个CharVar
。
使用引用的解决方案创建一个 IntVar
对象,然后为该对象创建一个新名称 (nr
),然后根据 [=] 的值更改该对象的值12=].
不能像对指针那样对引用进行变基。引用在其整个生命周期中引用同一个对象。
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