简体   繁体   English

指向类模板的指针

[英]pointer to class template

Here is the compilable code and the problem is still there 这是可编译的代码,问题仍然存在

#include <iostream>   
#include <string>    

template<typename A,typename B,typename C>   
class Mesh{   
    public:   
    Mesh(){}   
    Mesh(std::string file){   
    A foo;   
    std::cout <<  file << endl;   
    }   
};    

template<typename A, typename B,typename C>    
class Eq{    
public:    
  Mesh<A,B,C>* pmesh;      
  Eq() {}
  Eq(Mesh<A,B,C> *pmesh_){
      pmesh = pmesh_;
  }
};

template<typename A, typename B,typename C>
class Pipe{
public:
  Mesh<A, B,C> mesh;
  Eq<A, B, C> eq1;

  Pipe(){}
  Pipe(std::string file){
      mesh = Mesh<A, B, C>(file);
      eq1 = Eq<A,B,C>(&mesh);
      std::cout << "P:"<<&mesh << " ";
  }
};

template<typename A,typename B, typename C>
class Simulator {
public:
    Pipe<A,B,C> pipe;

    Simulator(){}
    Simulator(std::string file){
        pipe = Pipe<A,B,C>(file);
        std::cout << "S:"<<&(pipe.mesh)<<" ";
    }
};

using namespace std;
int main() {
    typedef double A;
    typedef double B;
    typedef int  C;

    Simulator< A, B, C> simu("mesh");
}

The Outlet of the program is 该程序的出口是

mesh 啮合
P:0018FE44 S:0018FE3C P:0018FE44 S:0018FE3C

I think the problem is in the declaration of pipe, if I define sinulator as 我认为问题出在管道的声明中,如果我将sinulator定义为

template<typename A,typename B, typename C>    
class Simulator {   
public:
    Pipe<A,B,C>*  ppipe;

Simulator(){}
    Simulator(std::string file){
        ppipe = new Pipe<A,B,C>(file);
        std::cout << "S:"<<&(ppipe->mesh)<<" ";
    }
};

the output is 输出是

mesh P:00308F08 S:00308F08 网孔P:00308F08 S:00308F08

any idea, why the first code is wrong ?? 任何想法,为什么第一个代码是错误的?

A compiling version of your code does not show the same behavior: 您的代码的编译版本不会显示相同的行为:

#include <iostream>
template<typename A> class Mesh{public: A foo; };

template<typename A>
struct Eq{
  Mesh<A>* pmesh;
  Eq(Mesh<A> *pmesh_){
      pmesh = pmesh_;
  }
  Eq() {}
};

template<typename A>
struct Pipe{
  Mesh<A> mesh;
  Eq<A> eq1;

  Pipe() {
      mesh = Mesh<A>();
      eq1 = Eq<A>(&mesh);
      std::cout << "P:"<<&mesh << " ";
  }
};
template<typename A>
struct Sim {
    Sim() {
        Pipe<A> pipe;
        std::cout << "S:"<<&(pipe.mesh)<<" ";
    }
};

int main() {
    Sim<int> bar;
}

Running it: 运行它:

[@foomanchu]$ ./temp
P:0x7fffffffeaf0 S:0x7fffffffeaf0 [@foomanchu]$ 

The problem is with your copy in the Simulator constructor. 问题在于您在Simulator构造函数中的副本。 This code should make things a bit more obvious. 这段代码应该使事情变得更加明显。

This has nothing to do with templates. 这与模板无关。

#include <iostream>

struct Mesh{ Mesh() { std::cout << "M:" << this << " ";} };

struct Pipe{
  Mesh mesh;

  Pipe() { std::cout << "PX:" << &mesh << " "; }
  Pipe(int file){
      std::cout << "P1:"<<&mesh << " ";
      mesh = Mesh();
      std::cout << "P2:"<<&mesh << " ";
  }
};

struct Simulator {
    Pipe pipe;

    Simulator(){
        std::cout << "S1:"<<&(pipe.mesh)<<" ";
        pipe = Pipe(2);
        std::cout << "S2:"<<&(pipe.mesh)<<" ";
    }
};

int main() {
    Simulator simu;
}

output: 输出:

:!./temp2
M:0x7fffffffea97 PX:0x7fffffffea97   <-- the setup of Simulator, before the constructor
S1:0x7fffffffea97
    M:0x7fffffffea96  <-- setup of the Pipe object, before the Pipe constructor
    P1:0x7fffffffea96 M:0x7fffffffea95 P2:0x7fffffffea96
S2:0x7fffffffea97

When you call the Simulator constructor, it first creates the object. 当您调用Simulator构造函数时,它首先创建对象。 Since one of the members is "Pipe pipe", that object is created at memory location ea97. 由于成员之一是“管道”,因此将在内存位置ea97中创建该对象。 Then we explicitly call the Pipe(std::string) constructor to create another object. 然后,我们显式调用Pipe(std :: string)构造函数以创建另一个对象。

In the Pipe constructor, the same thing is happening. 在Pipe构造函数中,发生了相同的事情。 We already have a Mesh object at ea96, but we create another one (at ea95) and copy it into that location with the built-in copy function. 我们在ea96处已经有一个Mesh对象,但是我们在ea95处创建了另一个对象,并使用内置的复制功能将其复制到该位置。

Then we're back to the Simulator constructor, where the newly created Pipe object is copied to the location of SimulatorObject.pipe (ea97). 然后,我们回到Simulator构造函数,在其中将新创建的Pipe对象复制到SimulatorObject.pipe(ea97)的位置。

EDIT: removing a few more pieces that don't matter... so you can see clearly when each constructor is being called. 编辑:删除更多无关紧要的部分...这样您就可以清楚地看到何时调用每个构造函数。

The syntax you're looking for is probably 您正在寻找的语法可能是

struct Simulator {
    Pipe pipe;

    Simulator(): pipe(2){
        std::cout << "S1:"<<&(pipe.mesh)<<" ";
    }
};

This will initialize the Pipe object inside Simulator "in-place". 这将在“就地”模拟器中初始化Pipe对象。 Note that this isn't a really big deal. 请注意,这并不是什么大不了的事情。 Your objects will copy when they're supposed to. 您的对象将在需要时复制。

If you have an object that can't be copied (it manages a database connection or something), you can forbid that by creating a copy constructor and an operator= overload that are both "private:" 如果您有一个无法复制的对象(它管理数据库连接之类的东西),则可以通过创建都为“ private:”的复制构造函数和operator =重载来禁止该对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM