在这种情况下,通过构造函数或显式函数进行隐式转换更好吗?

What is better implicit conversion through constructor or explicit function in this case?

我正在为 String 创建自己的 class,仅出于学习目的使用 C++。

我卡在了应该做决定的地方。让我解释一下。

我有两个选择 class。我将 post 下面仅显示相关代码段,因为我不想分散您对我手头问题的注意力。如果为了帮助我,您需要更多信息,我很乐意提供。

选项 1

class String {
    size_t _length;
    char* _stringHead;
public:
    String(const std::string&);
    String(const char*);
    String(const char);
};
String operator+(String, const String);

const bool operator==(const String, const String);
const bool operator!=(const String, const String);
const bool operator<(const String, const String);
const bool operator<=(const String, const String);
const bool operator>(const String, const String);
const bool operator>=(const String, const String);

选项 2

class String {
    size_t _length;
    char* _stringHead;
public:
    //irrelevant part of code in Option 2
    String(const std::string&);
    String(const char*);
    String(const char);
    //irrelevant part of code in Option 2
};
String operator+(String, const String&);

const bool operator==(const String&, const String&);
const bool operator!=(const String&, const String&);
const bool operator<(const String&, const String&);
const bool operator<=(const String&, const String&);
const bool operator>(const String&, const String&);
const bool operator>=(const String&, const String&);

//for std::string
String operator+(String, const std::string&);

const bool operator==(const String&, const std::string&);
const bool operator!=(const String&, const std::string&);
const bool operator<(const String&, const std::string&);
const bool operator<=(const String&, const std::string&);
const bool operator>(const String&, const std::string&);
const bool operator>=(const String&, const std::string&);

String operator+(const std::string&, String);

const bool operator==(const std::string&, const String&);
const bool operator!=(const std::string&, const String&);
const bool operator<(const std::string&, const String&);
const bool operator<=(const std::string&, const String&);
const bool operator>(const std::string&, const String&);
const bool operator>=(const std::string&, const String&);
//for std::string

//the same goes for char* and char
...
//the same goes for char* and char

因此,正如您从 选项 1选项 2 规范中看到的那样,这里的决定是关于是否使用隐式类型转换这是在构造函数的帮助下完成的,或者为我希望我的 String 类型工作的每种类型分别键入每个实用程序。

据我目前所知,使用第一种方法的好处是更易于实施和维护。而第二种方法可能会产生更好的性能结果。

我想得到建设性的论据,哪种方法更好,在什么情况下以及您会使用哪种方法。我认为我在这里最感兴趣的部分是第二种方法的性能优势是否合理。

在将参数类型的实例传递给需要 [=70= 的方法时,隐式构造函数用于 创建 class 类型的实例 ] 类型。这种隐式转换是通过调用 class.

的构造函数来完成的

例如,运行这段代码与你的相似:

#include <iostream>

class String {
 public:
  String(const std::string& s) {
    std::cout << "called" << std::endl;
  };
};

std::ostream& operator<< (std::ostream& stream, const String& s) {
  return stream;
}

void hello(String s) {
  std::cout << "Hello " << s; // Outputs "called" before "Hello ".
}

int main() {
  std::string s = "world";
  hello(s); // Uses the implicit conversion constructor.
}

因为每次都必须创建 class String 的新实例,所以预计 性能会略有下降 。但是,在我看来,这还不足以抵消好处:隐式转换可以极大地简化 class 设计人员的工作,并使 class 的使用更容易。

但是,请记住,在某些情况下,如果转化是自动发生的,团队成员更有可能感到惊讶,而不是因为转化的存在而得到帮助。

下面是这样一个例子:

#include <iostream>

class String {
 public:
  String(int size) {};
};

std::ostream& operator<< (std::ostream& stream, const String& s) {
    return stream;
}

void hello(String s) {
  std::cout << "Hello " << s; // Prints "Hello " as no error occurs.
}

int main() {
  hello(10); // It still calls the implicit conversion constructor.
}

在上面的代码中,explicit 关键字产生的错误消息可以节省一些调试时间。

隐式转换有意义的一些情况是:

  1. class 的构建成本低到足以让您不关心它是否是隐式构建的。
  2. 一些 classes 在概念上类似于它们的参数 ,例如 std::string 反映了与 const char* 相同的概念它可以隐含转换自,所以隐式转换是有意义的,就像这里的情况一样。
  3. 如果禁用隐式转换,一些 class 使用起来会更不愉快。 想想每次你都必须显式构造一个 std::string想要传递字符串文字。

隐式转换意义不大的一些情况是:

  1. 建设成本高
  2. 类 在概念上与他们的论点非常不同。 考虑 Stringint 的例子。
  3. 构造可能会产生不需要的副作用。例如,AnsiString class 不应该从 UnicodeString 隐式构造,因为Unicode 到 ANSI 的转换可能会丢失信息。

因此,在您的特定情况下,我的建议是使用转换,因为它很有意义,因为您的 class 与 std::string 非常相似,并且可以最大限度地减少代码重复,但在未来, 使用隐式转换思想