在访问私有元素时重载 << 运算符(朋友)
overloading << operator whilst accessing private elements (friend)
我正在编写一个程序,要求我在访问 class 的 private
成员时重载 <<
运算符。它是这样的:
A.h
#pragma once
#include <ostream>
#include "B.h"
using namespace std;
class A {
public:
A(B* b) {
this->b = b;
this->x = 0;
}
friend ostream& operator<<(ostream& os, A& a)
{
os << "this is a " << a.x;
return os;
}
private:
int x;
B* b;
};
B.h
#pragma once
#include <ostream>
using namespace std;
class B {
public:
B(int x) {
this->x = x;
}
friend ostream& operator<<(ostream& os, B& b)
{
os << "this is B " << b.x;
return os;
}
private:
int x;
};
main.cpp
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B* b = new B(1);
A* a = new A(b);
cout << a << endl;
cout << b << endl;
}
然而,这并没有打印a
和b
,只是这两个对象的内存地址。我认为这与操作顺序有关,但我不确定。
此外,我不能将 ostream& operator<<()
用作独立函数,因为那样会阻止我访问 class 的私有成员。
我可能会在 class 中实现 void print()
并使用它来打印私有成员,但我认为这不是我教授的想法(考虑到已经实现了 void print()
为了别的)。
在main()
中,a
和b
是指针。此代码:
cout << a
cout << b
实际上是调用这个:
cout.operator<<(a)
cout.operator<<(b)
因为std::ostream
有一个打印指针的成员operator<<(void*)
,所有指针都可以隐式转换为void*
。这就是您在输出中看到内存地址的原因。您的自定义运算符根本没有被调用,因为它们要求您将实际对象实例传递给 operator<<
,而您没有这样做。
您需要取消引用 main()
中的指针,例如:
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B* b = new B(1);
A* a = new A(b);
cout << *a << endl;
cout << *b << endl;
delete a;
delete b;
}
在此代码中:
cout << *a
cout << *b
由于 std::ostream
没有 A
或 B
的成员 operator<<
,这将有效地调用它:
operator<<(cout, *a)
operator<<(cout, *b)
这将调用您的自定义运算符。
否则,只需完全删除指针即可:
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B b(1);
A a(&b);
cout << a << endl;
cout << b << endl;
}
这也将有效地调用这个:
operator<<(cout, a)
operator<<(cout, b)
从而调用您的自定义运算符。
附带说明一下,您的自定义运算符应该接受对 const
A
+B
对象的引用,例如:
friend ostream& operator<<(ostream& os, const A& a)
friend ostream& operator<<(ostream& os, const B& b)
我正在编写一个程序,要求我在访问 class 的 private
成员时重载 <<
运算符。它是这样的:
A.h
#pragma once
#include <ostream>
#include "B.h"
using namespace std;
class A {
public:
A(B* b) {
this->b = b;
this->x = 0;
}
friend ostream& operator<<(ostream& os, A& a)
{
os << "this is a " << a.x;
return os;
}
private:
int x;
B* b;
};
B.h
#pragma once
#include <ostream>
using namespace std;
class B {
public:
B(int x) {
this->x = x;
}
friend ostream& operator<<(ostream& os, B& b)
{
os << "this is B " << b.x;
return os;
}
private:
int x;
};
main.cpp
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B* b = new B(1);
A* a = new A(b);
cout << a << endl;
cout << b << endl;
}
然而,这并没有打印a
和b
,只是这两个对象的内存地址。我认为这与操作顺序有关,但我不确定。
此外,我不能将 ostream& operator<<()
用作独立函数,因为那样会阻止我访问 class 的私有成员。
我可能会在 class 中实现 void print()
并使用它来打印私有成员,但我认为这不是我教授的想法(考虑到已经实现了 void print()
为了别的)。
在main()
中,a
和b
是指针。此代码:
cout << a
cout << b
实际上是调用这个:
cout.operator<<(a)
cout.operator<<(b)
因为std::ostream
有一个打印指针的成员operator<<(void*)
,所有指针都可以隐式转换为void*
。这就是您在输出中看到内存地址的原因。您的自定义运算符根本没有被调用,因为它们要求您将实际对象实例传递给 operator<<
,而您没有这样做。
您需要取消引用 main()
中的指针,例如:
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B* b = new B(1);
A* a = new A(b);
cout << *a << endl;
cout << *b << endl;
delete a;
delete b;
}
在此代码中:
cout << *a
cout << *b
由于 std::ostream
没有 A
或 B
的成员 operator<<
,这将有效地调用它:
operator<<(cout, *a)
operator<<(cout, *b)
这将调用您的自定义运算符。
否则,只需完全删除指针即可:
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B b(1);
A a(&b);
cout << a << endl;
cout << b << endl;
}
这也将有效地调用这个:
operator<<(cout, a)
operator<<(cout, b)
从而调用您的自定义运算符。
附带说明一下,您的自定义运算符应该接受对 const
A
+B
对象的引用,例如:
friend ostream& operator<<(ostream& os, const A& a)
friend ostream& operator<<(ostream& os, const B& b)