C ++模板,对象分配“静态”和“动态”的问题

时间:2011-04-02 19:07:59

标签: c++ templates

此代码有什么问题?

template <typename T>
class Sample
{
public:
    T first;
    T second;
    typedef T Type;
};

and 

template <typename Item> 
class Process
{
public:
    void process (Item *item) 
    {
        typename Item::Type var = item->first + item->second;
        //Some code...
    }
};

方法“进程”应该能够处理分配了“静态”和“动态”的对象......第一个选项有效

int main(int argc, _TCHAR* argv[])
{
Sample <double> s;
Process <Sample <double> > a;
a.process(&s);

return 0;
}

但第二个不是

int main(int argc, _TCHAR* argv[])
{

Sample <double> *s = new Sample <double>();
Process <Sample <double> *> a;
a.process(s); //Error  C2664: 'Process<Item>::process' : cannot convert parameter 1 from 'Sample<T> *' to 'Sample<T> *'
return 0;
}

如何设计一个类和方法“进程”,以便能够使用“静态”和“动态”分配的对象?谢谢你的帮助...

4 个答案:

答案 0 :(得分:3)

Process <Item>::process()需要Item*,因此Process <Sample <double> *>::process()需要Sample <double>**

然而,解决方案更容易:

Sample <double> *s = new Sample <double>();
Process <Sample <double> > a;
a.process(s);

对于Process,对象的分配方式无关紧要,它只是指向它的指针并与之一起工作(假设它不会保留所有权或试图删除对象)

答案 1 :(得分:2)

Sample <double> *s = new Sample <double>();
Process <Sample <double> *> a; //<<----------- here you go wrong!
a.process(s); 

Process的论点仍然是Sample<double>,而不是Sample<double>*,因为后者会Item* =&gt; Sample<double>**,在调用process成员函数时您没有通过。

所以正确的代码应该是这样的:

Process <Sample<double> > a; //<<----------- now it's correct!
a.process(s);

现在应该可以使用了!

或者这样做:

Sample <double> *s = new Sample <double>();
Process <Sample <double> *> a; //<------ your version!
a.process( &s );                 //<------ note I'm passing pointer to pointer!
       // ^^ note the ampersand (&)

答案 2 :(得分:2)

问题不在于对象是以某种方式分配的。至少虽然任何便携式的标准方法,但是不可能判断是否在堆栈上分配了一个对象,或者是否仅仅指定了它的指针。通过指针访问对象的成员对于“堆栈”对象和“自由存储”对象发生的方式完全相同。

实际问题是您将错误的类型传递给第二个代码段中的Process<>变量定义:

Process <Sample <double> *> a;

查看Process<>

的定义
template <typename Item>
class Process
{
public:
    void process (Item *item)
    { /* ... */ }
};

Item类型为Sample <double> *时,process()的函数签名将变为:

void process (Sample <double>** item)
{ /* ... */ }

显然,这不是你想要的。

要解决此问题,请更改

Process <Sample <double> *> a;

Process <Sample <double> > a;

使用后者,process()的函数签名变为void process (Sample <double>* item),这应该允许您的两个代码片段进行编译。

答案 3 :(得分:1)

Process <Sample <double> *> a;
a.process(s);

上述代码的Process.process签名为void process(Sample <double> **),因为ItemSample <double> * - 您希望它为void process(Sample <double> *)

改变这个:

Process <Sample <double> *> a;

要:

Process <Sample <double> > a;

如果查看完整的错误消息,编译器可能会告诉您在尝试将一个T与另一个Sample<T>匹配时使用的两个Sample<T>