如果指针的子类的方法对于子类是唯一的,如何访问这些方法?
How do I access a pointer's subclass's methods if those methods are unique to the subclass?
我的程序的一部分有两种可能的情况:(1(如果用户只给出2个命令行参数,则从标准输入(cin(中获取输入(2(如果用户给出3个命令行参数(最后一个是文件名(,则从文件中获取输入。为了不对两个选项重复使用相同的代码,我尝试使用指向 cin 和 ifstream 的超类的指针,istream 用于两种输入方式。
我的问题是,在下面代码的第 5 行和第 22 行,我试图引用仅适用于子类 ifstream 的方法(打开和关闭(。根据我的逻辑,如果调用这些方法,指针必须指向 if 流类型,但程序无法编译,因为这些方法未在 istream 类中定义。
有什么办法可以解决这个问题吗?
istream *currentStream;
if (argc == 3) {
// Handle optional file input
currentStream = new ifstream(argv[2]);
currentStream->open(argv[2]);
if (currentStream->fail()) {
cerr << "FILE COULD NOT BE OPENEDn";
return 1;
}
} else {
currentStream = &cin;
}
string myLine;
// go line by line and translate it
while (getline(*currentStream, myLine)) {
if (currentStream->eof()) {
break;
}
cout << rot13(myLine) << endl;
}
if (dynamic_cast<ifstream*>(currentStream)) {
currentStream->close();
}
// handle pointer
delete currentStream;
currentStream = NULL;
return 0;
通过获取缓冲区来动态分配std::cin
的"副本"。将内存存储在std::unique_ptr
中也是理想的选择,因为您不必担心手动删除指针。
#include <memory>
int main(int argc, char* argv[]) {
std::unique_ptr<std::istream> currentStream( argc == 3
? std::make_unique<std::ifstream>(argv[2])
: std::make_unique<std::istream>(std::cin.rdbuf())
);
// will only fail when the file cannot open
if (!currentStream) {
std::cerr << "FILE COULD NOT BE OPENEDn";
return 1;
}
std::string myLine;
// go line by line and translate it
while (std::getline(*currentStream, myLine)) {
std::cout << rot13(myLine) << std::endl;
}
}
有几个地方可以改进你的代码。我认为最突出的改进是你试图在一个功能中做太多。你不复制代码的目标是好的,但要模块化你的方法。将共享代码移动到其自己的函数,如下所示:
void do_stuff(std::istream & currentStream)
{
std::string myLine;
// go line by line and translate it
while (getline(currentStream, myLine)) {
if (currentStream.eof()) {
break;
}
std::cout << rot13(myLine) << std::endl;
}
}
此函数应包含两个代码路径之间共享的所有内容。(我将指针更改为引用,以便调用方立即知道空指针是不可接受的。当你改变你的主函数,让它调用这个函数时,你应该注意到一些事情变得更容易了。特别是,不需要动态分配(这导致没有尝试delete &cin
- 这看起来很糟糕(。您可以轻松地将局部变量用于文件流。
int main(int argc, const char ** argv)
{
if (argc == 3) {
// Handle optional file input
std::ifstream fileStream(argv[2]);
fileStream.open(argv[2]);
if (fileStream.fail()) {
std::cerr << "FILE COULD NOT BE OPENEDn";
return 1;
}
do_stuff(fileStream);
fileStream.close();
} else {
do_stuff(std::cin);
}
return 0;
}
通过将公共代码移动到单独的函数,您可以保留在if
子句中。无需推断*currentStream
是否需要关闭,因为您从未离开创建该文件的代码分支。
还有另一个地方可以简化事情。不要打电话给open
和close
.您正在使用采用文件名的ifstream
构造函数,因此构造函数已为您调用open
。(显式调用open
时,您告诉计算机关闭文件并重新打开它。同样,析构函数将为您调用close
;这是RAII的一个关键点。
摆脱不需要的呼叫会离开:
int main(int argc, const char ** argv)
{
if (argc == 3) {
// Handle optional file input
std::ifstream fileStream(argv[2]);
if (fileStream.fail()) {
std::cerr << "FILE COULD NOT BE OPENEDn";
return 1;
}
do_stuff(fileStream);
// Keep in mind that, even though there is no C++ code here, there is something
// important being done after the call to do_stuff. Specifically, the destructor
// for fileStream is called, which closes the file for you.
} else {
do_stuff(std::cin);
}
return 0;
}
只需提取一个方法:
void process(std::istream is) {
string myLine;
// go line by line and translate it
while (getline(is, myLine))
cout << rot13(myLine) << endl;
}
int main(int argc, char** argv) {
if (argc == 3) {
ifstream ifs(argv[2]);
if (!ifs) {
cerr << "FILE COULD NOT BE OPENEDn";
return 1;
}
process(ifs);
} else {
process(cin);
}
}
Tas在评论中采用了正确的方法。你不能直接在 currentStream 上调用该方法,你必须在 cast 接口上调用它。
ifstream* stream = dynamic_cast<ifstream*>(currentStream);
if (stream) {
stream->close();
}
我还认为您可能应该更改代码以不依赖于动态强制转换,无论是新接口还是单独的方法。
- 从父类方法返回子类对象
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 将子类方法声明为基类的友元
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- C++有没有办法强制重写一组方法,如果其中一个方法在子类中具有重写?
- C ++类型特征:确保子类实现方法
- 函数从唯一代码调用正确的子类方法
- Arduino在子类中使用父类方法
- C++强制在子类中实现方法,但具有不同的签名
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- 如何调用传递给 JNI 'jobject' 的 Java 对象的子类/子类的方法
- 将方法参数类型更改为子类中的派生类
- 如果指针的子类的方法对于子类是唯一的,如何访问这些方法?
- C++继承,如何在基类的方法中调用子类的方法?
- 在子类上调用模板化静态方法时获取类的类型名
- 检查子类是否执行了方法重写
- 将"this"从父类方法转换为子类方法是一种好的做法吗?
- 从C++中的父类实例访问子类方法
- 基类中的虚拟方法和子类中的非 Virtula 方法.仍然如何调用子类方法,即使它是非虚拟的
- C ,基础课程如何将子类作为成员包含并调用其方法