我有一个奇怪的问题。我以为我知道一定数量的C ++,但我必须忽略一些细微差别?
我有一些模板化的类,基本上所有发生的事情都是基于某种情况,一个对象正从一个std :: list移动到另一个。
这里关注的方法是doAndGet(T * t)。我的意图是以NULL
(或者其他什么,我真的不在乎,但它应该是NULL
或nullptr
进来,如果我最终移动T
1}}从*t
到myList
的元素myOtherList
,我希望T *t
指向已移动的项目。
现在也许有一些我不知道的std::list
,但是当我单步执行代码时,t
被正确分配 - 原来我想在返回的方法之后,但后来发现在ret
指令之前,参数T *t
被设置回NULL
任何一位大师能否对这个问题有所了解?对我来说这真是令人头疼......
template<typename T, typename C>
class Base : IsDerivedFrom<T, C>
{
public:
typedef std::list<T*> SpecialList;
virtual bool doAndGet( T* t ) = 0;
protected:
SpecialList myList;
};
template<typename T>
class Derived : public Base<T, Other>, public Other
{
public:
Derived( void );
virtual ~Derived( void );
bool doAndGet( T* t );
protected:
typename Base<T, Other>::SpecialList myOtherList;
};
template<typename T>
bool Derived<T>::doAndGet( T *t )
{
// Nothing to process
if (myOtherList.empty()) {return false;}
t = (*myOtherList.begin());
myOtherList.pop_front();
if (true/* some condition needs to be moved */)
{
t->status = 1;
this->myList.push_back(t);
return true;
} else
{
// Something bad happened...
delete t;
t = nullptr;
return false;
}
}
// Use... (pretend I defined MyOtherClass somewhere, not important)
Derived<MyOtherClass> derivedInstance;
MyOtherClass *t = nullptr;
if ( derivedInstance.doAndGet(t) )
{
// ... Here I should expect `t` to be not `NULL` and not `nullptr`
// This however, is not ever the case in my testing...
}
答案 0 :(得分:5)
如果要将变量传递给函数并在该函数中进行任何更改以反映回调用者,则需要使用引用。
与C一样,C ++是按值传递的,其中函数只获取变量的副本。 C ++引用了允许通过引用传递。换句话说,您的函数签名应为:
bool doAndGet( T* &t );
表示t
是对T*
的引用,允许更改反映回调用者中的原始指针。
一个更简单的例子如下:
#include <iostream>
static void change (int a, int &b) { a = b = 0; }
int main() {
int a = 42, b = 42;
change (a, b);
std::cout << a << ' ' << b << '\n';
return 0;
}
这会输出42 0
,因为传入的a
是按值传递的,更改不会反映回调用者。 b
作为参考传入,因此更改 反射回来。
答案 1 :(得分:1)
doAndGet
按值传递其参数。所以调用函数中的参数不会改变。
同样事情的简单例子:
void func(int x)
{
++x;
}
int main()
{
int y = 5;
func(y);
std::cout << y << "\n"; // outputs 5
}