吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 511|回复: 19
收起左侧

[求助] 有一个C++的问题想请教

[复制链接]
xihahaNextYear 发表于 2024-4-18 01:58
我这里自定义了一个模板类,然后想将方法定义和实现放到不同的文件中,按照之前的仿写了下,为什么这个一直报没有实例的错误 我检查了下 按照下面仿写的应该没有问题的,但是一直报错。请大佬们帮忙看看啥问题
https://github.com/carlesmartin85/procpp5e/blob/65aedda6a92745beca48a5041411465a33cdf4cd/code/c12_code/02_Grid/02_MethodsInInterfacePartition/GridDefinition.cppm
1. 创建了MyTestArray.cppm文件
[C++] 纯文本查看 复制代码
export module mytestarray;

export import :defv;
export import :impv;

2. 创建def模块接口文件
[C++] 纯文本查看 复制代码
module;
#include<cstddef>

export module mytestarray:defv;
import <utility>;
import <memory>;
import <stdexcept>;
import <iostream>;
import <format>;
export template<typename T>
class MyArray
{
public:
	MyArray();
	virtual ~MyArray();

	MyArray& operator=(const MyArray& myarray) = delete;
	MyArray(const MyArray& myarray) = delete;

	MyArray(MyArray&& src) noexcept;
	MyArray& operator=(MyArray&& rhs) noexcept;

	T& operator[](size_t x);
	const T& operator[](size_t x) const;

	const T& getElementAt(size_t x) const;

	void setElementAt(size_t x, const T& value);

	size_t getSize() const noexcept;
private:
	static const size_t AllocSize{ 4 };
	void resize(size_t newSize);
	T* m_elements{ nullptr };
	size_t m_size{ 0 };
};

3. 创建实现模块接口文件
[C++] 纯文本查看 复制代码
module;
#include <cstddef>
export module mytestarray:impv;

import :defv;
import <utility>;
import <memory>;
import <stdexcept>;
import <iostream>;
import <format>;
export template<typename T>
MyArray<T>::MyArray()
{
	m_size = AllocSize;
	m_elements = new T[m_size]{};
}

export template<typename T>
MyArray<T>::~MyArray()
{
	delete[] m_elements;
	m_elements = nullptr;
}

export template<typename T>
MyArray<T>::MyArray(MyArray&& src) noexcept
	: m_elements {std::exchange(src.m_elements, nullptr)}
	, m_size {std::exchange(src.m_size, 0)} {}

export template<typename T>
MyArray<T>& MyArray<T>::operator=(MyArray&& rhs) noexcept
{
	if (this == &rhs)
	{
		return *this;
	}

	delete[] m_elements;
	m_elements = std::exchange(rhs.m_elements, nullptr);
	m_size = std::exchange(rhs.m_size, 0);
	return *this;
}

export template<typename T>
void MyArray<T>::resize(size_t newSize)
{
	auto newArray{ std::make_unique<T[]>(newSize) };
	for (size_t i = 0; i < m_size; i++)
	{
		newArray[i] = m_elements[i];
	}

	delete[] m_elements;
	m_size = newSize;
	m_elements = newArray.release();
}


export template<typename T>
void MyArray<T>::setElementAt(size_t x, const T& val)
{
	if (x >= m_size)
	{
		resize(x + AllocSize);
	}

	m_elements[x] = val;
}


export template<typename T>
T& MyArray<T>::operator[](size_t x)
{
	// TODO: 在此处插入 return 语句
	//std::cout << std::format("call no-const function") << std::endl;
	if (x >= m_size)
	{
		resize(x + AllocSize);
	}
	return m_elements[x];
}

export template<typename T>
const T& MyArray<T>::operator[](size_t x) const
{
	// TODO: 在此处插入 return 语句
//	std::cout << std::format("call const function") << std::endl;
	if (x >= m_size)
	{
		throw std::out_of_range{ "" };
	}
	return m_elements[x];
}

//export template<typename T>
//const T& MyArray<T>::operator[](size_t) const
//{
//	// TODO: 在此处插入 return 语句
//	std::cout << format("call const function") << std::endl;
//	if (x >= m_size)
//	{
//		static T nullValue{ T() };
//		return nullValue;
//	}
//	return m_elements[x];
//}


export template<typename T>
const T& MyArray<T>::getElementAt(size_t x) const
{
	if (x >= m_size)
	{
		throw std::out_of_range{ "" };
	}
	return m_elements[x];
}

export template<typename T>
size_t MyArray<T>::getSize() const noexcept
{
	return m_size;
}


4. 导入模块,进行使用 但是报link的错误 应该是没有找到实例
[C++] 纯文本查看 复制代码
import mytestarray;

#include <iostream>;
using namespace std;

void printMyArray(const MyArray<int>& myarray)
{
	size_t total = myarray.getSize();
	for (size_t i = 0; i < total; i++)
	{
		cout << myarray[i] << " ";
	}
	cout << endl;
}

int main()
{
	MyArray<int> my;
	for (size_t i = 0; i < 10; i++)
	{
		my[i] = 1;
	}

	printMyArray(my);
	system("pause");
}



这个是显示的报错信息
1>D:\Project\CPlus\two\thir\CPlus\learnCPlus20\day14.cpp(192,31): warning C4101: “rerror”: 未引用的局部变量
1>day15.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall MyArray<int>::MyArray<int>(void)" (??0?$MyArray@H@@QAE@XZ::<!mytestarray>),函数 _main 中引用了该符号
1>day15.obj : error LNK2019: 无法解析的外部符号 "public: virtual __thiscall MyArray<int>::~MyArray<int>(void)" (??1?$MyArray@H@@UAE@XZ::<!mytestarray>),函数 _main 中引用了该符号
1>day15.obj : error LNK2019: 无法解析的外部符号 "public: int & __thiscall MyArray<int>::operator[](unsigned int)" (??A?$MyArray@H@@QAEAAHI@Z::<!mytestarray>),函数 _main 中引用了该符号
1>day15.obj : error LNK2019: 无法解析的外部符号 "public: int const & __thiscall MyArray<int>::operator[](unsigned int)const " (??A?$MyArray@H@@QBEABHI@Z::<!mytestarray>),函数 "void __cdecl printMyArray(class MyArray<int> const &)" (?printMyArray@@YAXABV?$MyArray@H@@@Z) 中引用了该符号
1>day15.obj : error LNK2019: 无法解析的外部符号 "public: unsigned int __thiscall MyArray<int>::getSize(void)const " (?getSize@?$MyArray@H@@QBEIXZ::<!mytestarray>),函数 "void __cdecl printMyArray(class MyArray<int> const &)" (?printMyArray@@YAXABV?$MyArray@H@@@Z) 中引用了该符号
1>D:\Project\CPlus\two\thir\CPlus\learnCPlus20\Debug\learnCPlus20.exe : fatal error LNK1120: 5 个无法解析的外部命令


发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

爱飞的猫 发表于 2024-4-18 06:25
本帖最后由 爱飞的猫 于 2024-4-18 06:32 编辑

模板不能将实现放到 cpp 文件内,因为没有构建对应的函数。

如果你真的需要分离,你得在 cpp 显示定义一份对应模板的变量,触发对应类型的模板函数编译。


看了下你给的例子用的是新的 module 语法,这个的话我不清楚了。上面的说明是只适用于非 module 语法的情况。

zsj118106 发表于 2024-4-18 08:07
如果按照普通函数一样,将模板函数的声明与定义的分开,声明放在头文件,定义放在cpp文件实现,你会发现,编译没问题,但是在链接阶段会报”undefined references“。
因此在实际开发中,不管是类模板还是模板函数,声明和定义最好放在一个文件中,一般是头文件。
yjtyejintian 发表于 2024-4-18 08:13
tyq2003 发表于 2024-4-18 08:14
学习学习
jamesAbc 发表于 2024-4-18 08:26
所有的模板不能和其他类的声明和实现那样分为cpp和hpp,而是要放在一个文件里面去声明和实现
迈克一 发表于 2024-4-18 08:37
这C++太新了我不会  但如果老款C++,原因是模板类需要写在一个文件里(声明和实现),而不是分.h和.cpp文件
nanaqilin 发表于 2024-4-18 08:44
模板与实现要放在一起,一般都放在头文件里,不能分开
whulife 发表于 2024-4-18 08:45
十余年的c++程序猿得瑟地进来然后一脸懵逼的走了
ytw6176 发表于 2024-4-18 08:51
whulife 发表于 2024-4-18 08:45
十余年的c++程序猿得瑟地进来然后一脸懵逼的走了

哈哈  我刚好在看c++视频,我说怎么跟我看的不一样,这下放心了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-12 21:45

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表