栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 类模板使用使用友元函数重载<<运算符的坑

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 类模板使用使用友元函数重载<<运算符的坑

开发平台:Microsoft Visual Studio 2022
错误提示:

C2248 “Vector::mBase”: 无法访问 private成员(在“Vector”类中声明) Project10 E:Microsoft Visual StudiocodeProject10Vector.hpp 72
C2248 “Vector::lenSize”: 无法访问 private成员(在“Vector”类中声明) Project10 E:Microsoft Visual StudiocodeProject10Vector.hpp 71

错误分析:这里的错误非常的无厘头,由于ostream使用了命名空间std的原因,而且以上代码在vc2010中完全可以过编译运行。

代码:
Vector.h

#pragma once
#include 

template
class Vector {
	
public:
	Vector(int lenSize);
	Vector(const Vector& other);
	T& operator[](int index) const;
	Vector& operator=(const Vector& other);
	int getLenSize() const;

	~Vector();
	
	template
	friend std::ostream& operator<<(std::ostream& cout, const Vector& other);  // 全局友元返回ostream实现  cout << a < 

Vector.hpp

#include  // memecpy_s

#include "Vector.h"

template
Vector::Vector(int lenSize) {
	if (lenSize > 0) {
		this->lenSize = lenSize;
		mBase = new T[lenSize];
		memset(mBase, 0, sizeof(T) * lenSize);
	}
}

template
Vector::Vector(const Vector& other) {
	// 这里存在问题mBase出现野指针,可以不用释放因为这个时候对象刚创建还没分配堆区空间
	//if (mBase) {
	//	delete[] mBase;
	//	mBase = NULL;
	//	lenSize = 0;
	//}

	lenSize = other.lenSize;
	mBase = new T[lenSize];
	//memcpy(mBase, other.mBase, sizeof(T)* other.lenSize); void* desc目标地址, void* src源地址,size字节数
	for (int i = 0; i < lenSize; i++) {
		mBase[i] = other.mBase[i];
	}

}

template
T& Vector::operator[](int index) const{
	return mBase[index];  // *(mBase+index);
}

template
Vector& Vector::operator=(const Vector& other) {
	if (mBase) {
		delete[] mBase;
		mBase = NULL;
		lenSize = 0;
	}

	lenSize = other.lenSize;
	mBase = new T[lenSize];
	//memcpy(mBase, other.mBase, sizeof(T) * other.lenSize);
	for (int i = 0; i < lenSize; i++) {
		mBase[i] = other.mBase[i];
	}

	return *this;  // v1 = v2 = v3;
}

template
int Vector::getLenSize() const {
	return lenSize;
}

template
Vector::~Vector() {
	if (mBase) {
		delete[] mBase;
		mBase = NULL;
		lenSize = 0;
	}
}

template
std::ostream& operator<<(std::ostream& cout, const Vector& other) {
	for (int i = 0; i < other.lenSize; i++) {
		cout << other.mBase[i] << " ";
	}
	
	return cout;
}

main.cpp

#include 
#include "Vector.hpp"
int main() {
	Vector v1(10);

	for (int i = 0; i < v1.getLenSize(); i++) {
		v1[i] = i*0.1f;
	}

	for (int i = 0; i < v1.getLenSize(); i++) {
		std::cout << v1[i] << std::endl;
	}


	Vector v2 = v1;

	for (int i = 0; i < v2.getLenSize(); i++) {
		std::cout << v2[i] << std::endl;
	}
	
	Vector v3(12);
	v3 = v2;

	for (int i = 0; i < v2.getLenSize(); i++) {
		std::cout << v3[i] << std::endl;
	}

	std::cout << v3 << std::endl;


	system("pause");
	return 0;
}

解决后的代码:

Vector.h

#pragma once
#include 
using namespace std;

template
class Vector {
	
public:
	Vector(int lenSize);
	Vector(const Vector& other);
	T& operator[](int index) const;
	Vector& operator=(const Vector& other);
	int getLenSize() const;

	~Vector();
	
	// 1、此处删除类模板声明
	// 2、使用using namspace std;
	//3、operator<<后面加上虚拟参数列表
	friend ostream& operator<<  (ostream& out, const Vector& other);  // 全局友元返回ostream实现  cout << a < 

Vector.hpp

#include  // memecpy_s

#include "Vector.h"

template
Vector::Vector(int lenSize) {
	if (lenSize > 0) {
		this->lenSize = lenSize;
		mBase = new T[lenSize];
		memset(mBase, 0, sizeof(T) * lenSize);
	}
}

template
Vector::Vector(const Vector& other) {
	// 这里存在问题mBase出现野指针,可以不用释放因为这个时候对象刚创建还没分配堆区空间
	//if (mBase) {
	//	delete[] mBase;
	//	mBase = NULL;
	//	lenSize = 0;
	//}

	lenSize = other.lenSize;
	mBase = new T[lenSize];
	//memcpy(mBase, other.mBase, sizeof(T)* other.lenSize); void* desc目标地址, void* src源地址,size字节数
	for (int i = 0; i < lenSize; i++) {
		mBase[i] = other.mBase[i];
	}

}

template
T& Vector::operator[](int index) const{
	return mBase[index];  // *(mBase+index);
}

template
Vector& Vector::operator=(const Vector& other) {
	if (mBase) {
		delete[] mBase;
		mBase = NULL;
		lenSize = 0;
	}

	lenSize = other.lenSize;
	mBase = new T[lenSize];
	//memcpy(mBase, other.mBase, sizeof(T) * other.lenSize);
	for (int i = 0; i < lenSize; i++) {
		mBase[i] = other.mBase[i];
	}

	return *this;  // v1 = v2 = v3;
}

template
int Vector::getLenSize() const {
	return lenSize;
}

template
Vector::~Vector() {
	if (mBase) {
		delete[] mBase;
		mBase = NULL;
		lenSize = 0;
	}
}

template
ostream& operator<<(ostream& out, const Vector& other) {
	for (int i = 0; i < other.lenSize; i++) {
		out << other.mBase[i] << " ";
	}
	
	return out;
}

main.cpp

#include 
#include "Vector.hpp"

int main() {
	Vector v1(10);

	for (int i = 0; i < v1.getLenSize(); i++) {
		v1[i] = i*0.1f;
	}

	for (int i = 0; i < v1.getLenSize(); i++) {
		std::cout << v1[i] << std::endl;
	}


	Vector v2 = v1;

	for (int i = 0; i < v2.getLenSize(); i++) {
		std::cout << v2[i] << std::endl;
	}
	
	Vector v3(12);
	v3 = v2;

	for (int i = 0; i < v2.getLenSize(); i++) {
		std::cout << v3[i] << std::endl;
	}

	std::cout << v3 << std::endl;

	return 0;
}

解决方法:

1、删除友元函数声明上面的类模板声明
2、使用using namspace std;,不用使用std::ostream
3、operator<<后面加上虚拟参数列表

以上代码在VS2022和VC2010中均可过编译运行

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/971124.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号