我有一个相当标准的情况,我希望以下列方式使用模板化的类:
在我尝试的每个其他编译器(即g ++和clang / llvm)中,这都可以正常工作。在visual studio中,它告诉我文件已经定义。
如果我手动剪切并将.cpp中的文本粘贴到.h文件中,那么一切正常。我的印象是,这正是#include
应该做的。
我的预感是,visual studio正在以某种方式不止一次地编译.cpp文件(虽然我将#pragma once
放在.h和.cpp文件上。)
发生了什么,以及如何让我的模板类在VS中运行?
代码如下:
.h:
#pragma once
template <class T>
class myVector
{
private:
void grow();
public:
int size;
int index;
T** words;
void pushBack(T* data);
inline T* operator[](int);
myVector(void);
~myVector(void);
};
#include "myVector.cpp"
的.cpp:
#pragma once
#include "stdafx.h"
#include <cstdlib>
#include "myVector.h"
#include <iostream>
using namespace std;
template<class T>
myVector<T>::myVector(void)
{
this->size = 2000;
words = new T*[size];
index=0;
}
template<class T>
void myVector<T>::pushBack(T* input)
{
if(index<size)
{
words[index]=input;
}
else
{
grow();
words[index]=input;
}
index++;
}
template<class T>
T* myVector<T>::operator[](int i)
{
return words[i];
}
template<class T>
void myVector<T>::grow()
{
//cout<<"I grew:"<<endl;
size*=2;
words = (T**)realloc(words,size*sizeof(T*));
}
template<class T>
myVector<T>::~myVector(void)
{
delete[] words;
}
答案 0 :(得分:2)
在我看来,你的困惑源于不知道#pragma once
和翻译单位的运作方式。
#pragma once
,就像包含警卫一样,可以防止将文件内容(通常是标题)多次拉入单个翻译单元。
如果您在多个实施文件中#include <vector>
,则会在所有文件中提取内容,但每个翻译单元只会提取一次。
所以你应该删除#include "myVector.cpp"
,因为MSVS会自动编译实现文件,而且它也是错的。
请注意,模板定义必须是可见的,因此您需要将其移至.h
文件,就像您一样,或者使用您当前的方法重命名.cpp
将文件归档为.impl
甚至.h
,并将其包含在内。