按照你的修改了,你看下我帖子上面的图片,运行就是这样了 baige 发表于 2020-8-8 16:51
我还是没有解决按照你说的,能给我远程看看吗,我给你发红包呀{:5_103:} 不知道,我可以正常运行,我实现还是写在cpp上,声明写在.h上,只是出现主函数无法解析 加上#include "Vector.cpp"就可以正常运行
,没有出现你的情况 试了下,可以正常编译执行,下面是完整代码,三个文件,其中有几个小修改,
你复制完整代码看正常不。我是在VS2015下运行的。
//Vector.h
#ifndef VECTOR_H_
#define VECTOR_H_
#define SUCCESS 1 // 成功
#define ERROR -1 // 失败
#define MALLOC_ERROR -2 // 申请内存失败
#define INDEX_ERROR -3 // 错误的索引号
template<class T_ELE>
class Vector
{
private:
T_ELE *pVector;
int Len;
int Index;
int InitSize;
int Increment;
public:
Vector<T_ELE>();
Vector<T_ELE>(int size);
~Vector<T_ELE>();
int push_back(T_ELE Element);
bool expand();
int insert(int index, T_ELE Element);
};
#endif
//Vector.cpp
#include "Vector.h"
template<class T_ELE>
Vector<T_ELE>::Vector() : InitSize(100), Increment(5)
{
//分配空间
//pVector = new T_ELE(InitSize);
pVector = new T_ELE;
//初始化
memset(pVector, 0, InitSize * sizeof(T_ELE));
//其他变量初始化
Len = InitSize;
Index = 0;
}
template<class T_ELE>
Vector<T_ELE>::Vector(int size) : Increment(5)//增加了Increment(5)
{
//分配空间
//pVector = new T_ELE(size);
pVector = new T_ELE;
//初始化
memset(pVector, 0, size * sizeof(T_ELE));
//其他变量初始化
Len = size;
Index = 0;
}
template<class T_ELE>
Vector<T_ELE>::~Vector()
{
//释放类对象里面申请的空间
delete[]pVector;
pVector = NULL;
}
template<class T_ELE>
int Vector<T_ELE>::push_back(T_ELE Element)
{
//判断是否需要增容
if (Index >= Len)
{
expand();
}
//将新元素放到最后一个位置
memcpy(&pVector, &Element, sizeof(T_ELE));
//修改索引
Index++;
//返回成功
return SUCCESS;
}
//扩容
template<class T_ELE>
bool Vector<T_ELE>::expand()
{
int tlen;
int* pNew;
//计算增加后的长度
tlen = Len + Increment;
//申请现在需要的空间
//pNew = new T_ELE(tlen);
pNew = new T_ELE;
//将数据复制到新空间
memcpy(pNew, pVector, Len*sizeof(T_ELE));
//释放原来的空间
delete[]pVector;
pVector = pNew;
pNew = NULL;
//修改其他变量值
Len = tlen;
return SUCCESS;
}
//插入数据
template<class T_ELE>
int Vector<T_ELE>::insert(int index, T_ELE Element)
{
//判断索引是否在合理区间
if (index<0 || index>Index)
return INDEX_ERROR;
//判断是否需要扩容
if (Index >= Len)
expand();
//将索引后面的元素全部后移
for (int i = Index; i>index - 1; i--)
memcpy(&pVector, &pVector, sizeof(T_ELE));
//将元素插入对应的位置
memcpy(&pVector, &Element, sizeof(T_ELE));
//修改其他对应的参数
Index++;
}
//test.cpp
#include<iostream>
#include <string.h>
#include "Vector.h"
#include "Vector.cpp"
using namespace std;
//测试函数
void TextVector()
{
Vector<int>* p = new Vector<int>(5);
p->push_back(1);
p->push_back(2);
p->push_back(3);
p->push_back(4);
p->push_back(5);
p->push_back(6);
}
int main()
{
TextVector();
return 0;
} superbe 发表于 2020-8-8 17:51
试了下,可以正常编译执行,下面是完整代码,三个文件,其中有几个小修改,
你复制完整代码看正常不。我是 ...
非常感谢,你修改了哪里呀,能否标柱一下呀 本帖最后由 superbe 于 2020-8-9 09:47 编辑
修改的地方见Vector.cpp文件里的注释行:
第7行 pVector = new T_ELE(InitSize);
第20行pVector = new T_ELE(size);
第61行pNew = new T_ELE(tlen);
上面几行把new T_ELE后面的小括号改成了中括号,表示分配数组
第17行Vector<T_ELE>::Vector(int size) : Increment(5)
这行增加了初始化Increment(5),避免调用Vector(int size)构造函数时Increment没有初始化,后面expand里就会出错。
头文件Vector.h里增加了三行预编译指令,防止重复包含:
#ifndef VECTOR_H_
#define VECTOR_H_
......
#endif superbe 发表于 2020-8-9 09:43
修改的地方见Vector.cpp文件里的注释行:
第7行 pVector = new T_ELE(InitSize);
好的,非常感谢你指出的错误。最后3个指令有个疑问,比如我写一个简单Person类,没有用这3个指令可以通过,如果用了这个指令会错误,比如这个目前可以正常运行。同样都是类,为什么我上面Vector的类去掉这3个指令就出错呀,而下面这个不会出错。这里真的很纳闷,希望能解答一下,非常感谢
Person.h
#pragma once
class Person
{
public:
int x;
public:
Person();
};
Person.cpp
#include "Person.h"
#include<iostream>
using namespace std;
Person::Person()
{
cout << "构造函数的实现" << endl;
}
main()
#include <iostream>
#include "Person.h"
int main()
{
Person p;
}
本帖最后由 superbe 于 2020-8-9 13:33 编辑
Person程序把#pragma once去掉仍然正常,是因为main文件里只包含了一次"Person.h",不会发生重复定义的问题。
Vector程序main文件有#include "Vector.h" 和 #include "Vector.cpp",而后者内部已经有了一行#include "Vector.h"。这样实际上在main文件里包含了两次Vector.h,所以发生重复定义class Vector的问题。
在Vector程序main文件中把#include "Vector.h"这行去掉(这里这行不必要),再把#ifndef VECTOR_H_等三行(或#pragma once)去掉也就正常了。
书上是建议把模板声明和定义放在同一个头文件中的,参考下《C++ Primer》中的说法:
通常,当我们调用一个函数时,编译器只需要掌握函数的声明。类似的,当我们使用一个类类型的对象时,类定义必须是可用的,但成员函数的定义不必已经出现。因此,我们将类定义和函数声明放在头文件中,而普通函数和类的成员函数的定义放在源文件中。
模板则不同:为了生成一个实例化版本,编译器需要掌握函数模板或类模板成员函数的定义。因此,与非模板代码不同,模板的头文件通常既包括声明也包括定义。
Note: 函数模板和类模板成员函数的定义通常放在头文件中。
superbe 发表于 2020-8-9 13:06
Person程序把#pragma once去掉仍然正常,是因为main文件里只包含了一次"Person.h",不会发生重复定义的问题 ...
在Vector程序main文件中把#include "Vector.h"这行去掉(这里这行不必要),再把#ifndef VECTOR_H_等三行(或#pragma once)去掉也就正常了。
试了一下这个可以。但是在Vector程序main文件中把#include "Vector.cpp"这行去掉,
保留Vector.h,把#ifndef VECTOR_H_等三行(或#pragma once)去掉,却不正常 你看错了,我说的是去掉#include "Vector.h",不是#include "Vector.cpp"
页:
1
[2]