如何通过运算符<<的重载访问受保护的功能?C++

How to access to a protected function with the overloading of the operator << ? C++

本文关键字:lt 功能 C++ 受保护 访问 何通过 重载 运算符      更新时间:2023-10-16

对于C++练习,我必须在使运算符重载<<的函数中使用受保护的 c++。

但是我们知道,如果我们想在 cpp 文件中定义函数,可以在类中或使用关键字 friend 访问受保护的函数。

目前,我有一个抽象类和主要类。

我不知道如何修复此错误,我想尽早完成此练习;)

卡.hpp

#ifndef CARD_HPP
#define CARD_HPP
#include <string>
#include <iostream>
class Card
{
std::string name;
protected:
virtual std::ostream & toStream(std::ostream & out){out << name;return out;}
public:
Card(std::string n):name(n){}
friend std::ostream & operator<<(std::ostream & out, const Card  &c);        
};
#endif

卡.cpp

#include <Card.hpp>
std::ostream & operator<<(std::ostream & out, const Card  &c)
{
return c.toStream(out);
}

主.cpp

#include <Card.hpp>
using namespace std;
int main()
{
Card card("montain");
cout << card << "n";
return 0;
}

输出

clang++ -Wall -std=c++14 -c -o obj/main.o src/main.cpp -I include
clang++ -Wall -std=c++14 -c -o obj/Card.o src/Card.cpp -I include
src/Card.cpp:5:12: error: member function 'toStream' not viable: 'this' argument has type 'const Card', but function is not
marked const
return c.toStream(out);
^
include/Card.hpp:12:32: note: 'toStream' declared here
virtual std::ostream & toStream(std::ostream & out){out << name;return out;}
^
1 error generated.
makefile:16: recipe for target 'obj/Card.o' failed
make: *** [obj/Card.o] Error 1

生成文件

CC = clang++
CFLAGS = -Wall -std=c++14
HDIR = include
ABSTRACT = obj/Card.o
.PHONY: doc
compile: bin/main
./bin/main
bin/main: obj/main.o ${ABSTRACT}
${CC} ${CFLAGS} -o $@ $^
obj/%.o: src/%.cpp
${CC} ${CFLAGS} -c -o $@ $< -I ${HDIR}
doc:
doxygen Doxyfile
clean: 
rm obj/*.o
rm bin/*
cleanDoc:
rm doc/* -rf

问题不在于该功能受到保护,而在于它不const

src/Card.cpp:5:12: error: member function 'toStream' not viable: 'this' argument has type 'const Card', but function is not
marked const
return c.toStream(out);

正如错误消息所说,由于const Card &ccconst,并且您只能在c上调用 const 成员函数。

因此,要么将toStream成员函数设置为const

virtual std::ostream & toStream(std::ostream & out) const

或者更改流式处理运算符,以便c不是常量。但不建议这样做,如果函数需要更改/替换传递的参数,则只应作为非常量引用传递:

std::ostream & operator<<(std::ostream & out, Card  &c)