我有一个模板类,似乎在一次测试中失败了。
- 模板结构"term"表示表达式图的节点值。
- 有一个模板结构"expression"表示图形。 有一个测试过程"void test ()"
void Test()
{
cout << "**** Integer Tests" << endl;
// Default Constructor
integer a;
cout << "integer a = "<< a.Value << endl;
// Copy Constructor
integer b(a);
cout << "integer b(a) = "<< b.Value << endl;
integer c = b;
cout << "integer c = b = "<< c.Value << endl;
// Type Constructor
integer d(5);
cout << "integer d(5) = "<< d.Value << endl;
integer e = 5;
cout << "integer e = 5 = "<< e.Value << endl;
// Type Conversions
int n = e.Value;
cout << "n = e = "<< n << endl;/
n = (int)d.Value + (int)e.Value;
cout << "n = d + e = "<< n << endl;// allowed because a convers to int
cout << "**** Expression Tests" << endl;
expression<int> e1;
expression<int> e2(e1);
expression<int> e3(d);// This line using the copy constructor works
expression<int> e4 = d + e;// this line, using the copy constructor AFTER the operator+ call results in BUM values.
}
测试函数"void test()"未能为语句给出正确的值:
表达式e4 = d + e;
遍历调用堆栈…在T + 1
1.)调用term::expression&操作符+ (term&ref)
2.)返回时,表达式节点的左右值都是正确的!!
3.)现在,赋值失败了…它调用复制构造函数表达式(expression&ref)
4)。WTF ? ?在这里面,我得到了不值钱的左值和右值。
为什么,当复制构造函数测试在上面那行成功时?
下面是测试用例模板
template<typename T> struct expression; // Forward Declare expressions, so i can use it in operator+
template<typename T>
struct term
{
T Value;
term() : Value(0)
{
cout << "**** term()" << endl;
} // Default Constructor
term(term& ref) : Value(ref.Value)
{
cout << "**** term(term& ref)" << endl;
} // Copy Constructor
// Type Conversion
term(T value) : Value(value)
{
cout << "**** term(T value)" << endl;
} // Type Constructor
//operator T() const { return Value; } // Type Converter
**expression<T>& operator+(term& ref)
{
return expression<T>(*this, ref);
};**
};
template<typename T>
struct expression
{
term<T> Left;
term<T> Right;
expression()
: Left()
, Right()
{
cout << "**** expression()" << endl;
cout << "left" << Left.Value << endl;
cout << "right" << Right.Value << endl;
}
expression(expression& ref)
: Left(ref.Left)
, Right(ref.Right)
{
cout << "**** expression(expression& ref)" << endl;
cout << "left" << Left.Value << endl;
cout << "right" << Right.Value << endl;
}
expression(term<T>& left)
: Left(left)
, Right()
{
cout << "**** expression(term<T>& left)" << endl;
cout << "left" << Left.Value << endl;
cout << "right" << Right.Value << endl;
}
expression(term<T>& left, term<T>& right)
: Left(left)
, Right(right)
{
cout << "**** expression(term<T>& left, term<T>& right)" << endl;
cout << "left" << Left.Value << endl;
cout << "right" << Right.Value << endl;
}
};
struct integer : public term<int>
{
integer() : term() { }// allows default constructor (not inheritablle)
// tactic to get base class constructors(1 parameter) to compile...
template<class T> integer(T t) : term(t) { }
//template<class T> integer(T& t) : term(t) { }
};
void Test()
{
cout << "**** Integer Tests" << endl;
// Default Constructor
integer a;
cout << "integer a = "<< a.Value << endl;// allowed because integer converts to int
// Copy Constructor
integer b(a);
cout << "integer b(a) = "<< b.Value << endl;
integer c = b;
cout << "integer c = b = "<< c.Value << endl;
// Type Constructor
integer d(5);
cout << "integer d(5) = "<< d.Value << endl;
integer e = 5;
cout << "integer e = 5 = "<< e.Value << endl;
// Type Conversions
int n = e.Value;
cout << "n = e = "<< n << endl;// allowed because a convers to int
// Arithmetic using base type operators... whatever they allow, is allowed.
n = (int)d.Value + (int)e.Value;
cout << "n = d + e = "<< n << endl;// allowed because a convers to int
cout << "**** Expression Tests" << endl;
expression<int> e1;
expression<int> e2(e1);
expression<int> e3(d);// This line using the copy constructor works
expression<int> e4 = d + e;// this line, using the copy constructor AFTER the operator+ call results in BUM values.
}
以上代码的输出如下所示:
**** Integer Tests
**** term()
integer a = 0
**** term(term& ref)
integer b(a) = 0
**** term(term& ref)
integer c = b = 0
**** term(T value)
integer d(5) = 5
**** term(T value)
integer e = 5 = 5
n = e = 5
n = d + e = 10
**** Expression Tests
**** term()
**** term()
**** expression()
left0
right0
**** term(term& ref)
**** term(term& ref)
**** expression(expression& ref)
left0
right0
**** term(term& ref)
**** term()
**** expression(term<T>& left)
left5
right0
**** term(term& ref)
**** term(term& ref)
**** expression(term<T>& left, term<T>& right)
left5
right5
**** term(term& ref)
**** term(term& ref)
**** expression(expression& ref)
left4061292
right4061296
Edit:正如所指出的(很快,我可能会补充),操作符+返回对堆栈上临时值的引用,而不是我假设的值。
函数被修正,使得表达式后的&符号被移除:
expression<T> operator+(term& ref)
{
return expression<T>(*this, ref);
};
这是ID10T错误。&符号就在我面前。
再次感谢你帮我解决这个问题。你的问题是:
expression<T>& operator+(term& ref)
operator+
应该返回一个新对象。您正在返回对临时对象的引用。那应该已经编译了,但我猜你正在使用MSVC,它有一个扩展来允许这个原因,我不明白。
在你的代码中有其他问题,应该阻止它编译,但这可能是导致你的错误。作为第一个近似,代码中使用的每个引用都是不正确的-它们都应该是对const
或值的引用。