这是可编译的代码,问题仍然存在
#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");
}
该计划的出口是
目
P:0018FE44 S:0018FE3C
我认为问题出在管道声明中,如果我将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)<<" ";
}
};
输出
目 P:00308F08 S:00308F08
任何想法,为什么第一个代码错了?
答案 0 :(得分:0)
您的代码的编译版本不会显示相同的行为:
#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;
}
运行它:
[@foomanchu]$ ./temp
P:0x7fffffffeaf0 S:0x7fffffffeaf0 [@foomanchu]$
答案 1 :(得分:0)
问题在于您在Simulator构造函数中的副本。这段代码应该让事情变得更加明显。
这与模板无关。
#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;
}
输出:
:!./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
当您调用Simulator构造函数时,它首先创建对象。由于其中一个成员是“Pipe pipe”,因此该对象是在内存位置ea97创建的。然后我们显式调用Pipe(std :: string)构造函数来创建另一个对象。
在Pipe构造函数中,同样的事情正在发生。我们已经在ea96上有一个Mesh对象,但我们创建了另一个(在ea95)并使用内置的复制功能将其复制到该位置。
然后我们回到Simulator构造函数,在那里将新创建的Pipe对象复制到SimulatorObject.pipe(ea97)的位置。
编辑:删除一些无关紧要的部分......这样你就可以清楚地看到每个构造函数的调用时间。
您正在寻找的语法可能是
struct Simulator {
Pipe pipe;
Simulator(): pipe(2){
std::cout << "S1:"<<&(pipe.mesh)<<" ";
}
};
这将在“就地”模拟器内初始化Pipe对象。请注意,这不是什么大问题。您的对象将在它们应该复制时复制。
如果你有一个无法复制的对象(它管理数据库连接或其他东西),你可以通过创建一个复制构造函数和一个都是“private:”的operator = overload来禁止它。