C ++使用toString()方法有什么问题 [英] C++ What is wrong with using a toString() method

查看:672
本文介绍了C ++使用toString()方法有什么问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚遇到这个问题,该问题与如何打印对象有关通过

std::cout << x << std::endl;

据我了解,完成此操作的标准方法是使ostream超载<<操作员.但是,这是向ostream而非我的班级添加了功能.

替代方法(也提供上述问题的答案)是重写字符串转换运算符.但是,这带有警告,可能会导致意外转换和难以跟踪的错误".

现在,我想知道编写toString()方法然后通过以下方式使用它是否有任何缺点

std::cout << x.toString() << std::endl;

解决方案

输出流既可以处理输出格式,也可以处理输出.因此,使用您的toString()方法,客户端将无法像处理其他所有操作一样管理对象的格式:

// set specific formatting options for printing a value
std::cout << std::scientific << std::setprecision(10) << 10.0 << '\n'; // prints 1.0000000000e+01

// set formatting based on user's cultural conventions
std::cout.imbue(std::locale(""));
std::cout << 10000000 << '\n'; // depending on your system configuration may print "10,000,000"

也许您不在乎允许任何格式,所以也许这无关紧要.

另一个考虑因素是,输出到流并不需要立即将整个字符串表示形式存储在内存中,但是您的toString()方法却需要.


其他人指出了这一点,但是我认为更清晰的说法是,您的类接口不仅限于它提供的方法,还包括围绕它构建的其他函数,包括非成员函数,例如作为您提供的operator<<重载.即使它不是您班级的方法,您仍应将其视为班级接口的一部分.

这是一篇有关此问题的文章,也许对您有所帮助: 非成员函数如何改善封装


这是一个为用户定义的类重载operator<<的简单示例:

#include <iostream>

struct MyClass {
  int n;
};

std::ostream &operator<< (std::ostream &os, MyClass const &m) {
  for (int i = 0; i < m.n; ++i) {
    os << i << ' ';
  }
  return os;
}

int main() {
  MyClass c = {1000000};
  std::cout << c << '\n';
}

I just came across this question which is about how to be able to print an object via

std::cout << x << std::endl;

As I understood, the standard way to accomplish this is to overload the ostreams << operator. However, this is adding a feature to the ostream rather than to my class.

The alternative (also given as answer to the above mentioned question) is to override the string conversion operator. However, this comes with the warning of leading to "unintentional conversions and hard-to-trace bugs".

Now i wonder if there are any drawbacks of writing a toString() method and then using it via

std::cout << x.toString() << std::endl;

解决方案

Output streams handle output formatting as well as output. So with your toString() method clients won't be able to manage the formatting for the object the way they do for everything else:

// set specific formatting options for printing a value
std::cout << std::scientific << std::setprecision(10) << 10.0 << '\n'; // prints 1.0000000000e+01

// set formatting based on user's cultural conventions
std::cout.imbue(std::locale(""));
std::cout << 10000000 << '\n'; // depending on your system configuration may print "10,000,000"

Perhaps you don't care to allow any formatting so perhaps this won't matter.

Another consideration is that outputting to a stream doesn't require that the entire string representation be in memory at once, but your toString() method does.


Others have pointed this out, but I think a clearer way of saying it is that your classes interface is not limited to just the methods it provides, but also includes the other functions you build around it, including non-member functions such as the operator<< overloads you provide. Even though it's not a method of your class you should still think of it as part of your class's interface.

Here's an article that talks about this which perhaps you will find helpful: How Non-Member Functions Improve Encapsulation


Here's a simple example of overloading operator<< for a user defined class:

#include <iostream>

struct MyClass {
  int n;
};

std::ostream &operator<< (std::ostream &os, MyClass const &m) {
  for (int i = 0; i < m.n; ++i) {
    os << i << ' ';
  }
  return os;
}

int main() {
  MyClass c = {1000000};
  std::cout << c << '\n';
}

这篇关于C ++使用toString()方法有什么问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆