开发平台:Microsoft Visual Studio 2022
错误提示:
C2248 “Vector::mBase”: 无法访问 private成员(在“Vector”类中声明) Project10 E:\Microsoft Visual Studio\code\Project10\Vector.hpp 72
C2248 “Vector::lenSize”: 无法访问 private成员(在“Vector”类中声明) Project10 E:\Microsoft Visual Studio\code\Project10\Vector.hpp 71
错误分析:这里的错误非常的无厘头,由于ostream使用了命名空间std的原因,而且以上代码在vc2010中完全可以过编译运行。
代码:
Vector.h
#pragma once
#include <iostream>
template<typename T>
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<typename T>
friend std::ostream& operator<<(std::ostream& cout, const Vector& other); // 全局友元返回ostream实现 cout << a <<b,类内部友元只能 a<<cout
private:
int lenSize;
T* mBase; // 数组数据指针
};
Vector.hpp
#include<string.h> // memecpy_s
#include "Vector.h"
template<typename T>
Vector<T>::Vector(int lenSize) {
if (lenSize > 0) {
this->lenSize = lenSize;
mBase = new T[lenSize];
memset(mBase, 0, sizeof(T) * lenSize);
}
}
template<typename T>
Vector<T>::Vector(const Vector<T>& 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<typename T>
T& Vector<T>::operator[](int index) const{
return mBase[index]; // *(mBase+index);
}
template<typename T>
Vector<T>& Vector<T>::operator=(const Vector<T>& 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<typename T>
int Vector<T>::getLenSize() const {
return lenSize;
}
template<typename T>
Vector<T>::~Vector() {
if (mBase) {
delete[] mBase;
mBase = NULL;
lenSize = 0;
}
}
template<typename T>
std::ostream& operator<<(std::ostream& cout, const Vector<T>& other) {
for (int i = 0; i < other.lenSize; i++) {
cout << other.mBase[i] << " ";
}
return cout;
}
main.cpp
#include <iostream>
#include "Vector.hpp"
int main() {
Vector<float> 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<float> v2 = v1;
for (int i = 0; i < v2.getLenSize(); i++) {
std::cout << v2[i] << std::endl;
}
Vector<float> 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 <iostream>
using namespace std;
template<typename T>
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<<后面加上虚拟参数列表<T>
friend ostream& operator<< <T> (ostream& out, const Vector& other); // 全局友元返回ostream实现 cout << a <<b,类内部友元只能 a<<cout
private:
int lenSize;
T* mBase = NULL; // 数组数据指针
};
Vector.hpp
#include<string.h> // memecpy_s
#include "Vector.h"
template<typename T>
Vector<T>::Vector(int lenSize) {
if (lenSize > 0) {
this->lenSize = lenSize;
mBase = new T[lenSize];
memset(mBase, 0, sizeof(T) * lenSize);
}
}
template<typename T>
Vector<T>::Vector(const Vector<T>& 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<typename T>
T& Vector<T>::operator[](int index) const{
return mBase[index]; // *(mBase+index);
}
template<typename T>
Vector<T>& Vector<T>::operator=(const Vector<T>& 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<typename T>
int Vector<T>::getLenSize() const {
return lenSize;
}
template<typename T>
Vector<T>::~Vector() {
if (mBase) {
delete[] mBase;
mBase = NULL;
lenSize = 0;
}
}
template<typename T>
ostream& operator<<(ostream& out, const Vector<T>& other) {
for (int i = 0; i < other.lenSize; i++) {
out << other.mBase[i] << " ";
}
return out;
}
main.cpp
#include <iostream>
#include "Vector.hpp"
int main() {
Vector<float> 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<float> v2 = v1;
for (int i = 0; i < v2.getLenSize(); i++) {
std::cout << v2[i] << std::endl;
}
Vector<float> 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中均可过编译运行