在这种情况下,通过构造函数或显式函数更好的隐式转换是什么?

hel*_*udo 6 c++ constructor explicit header class

我正在创建自己的类,String仅用于学习目的.

我坚持到应该做出决定的地方.让我解释一下这件事.

我有两个班级选择.我将在下面仅发布相关的代码片段,因为我不想分散您对我手头的问题的注意力.如果为了帮助我,你需要更多信息,我很乐意提供.

选项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);
Run Code Online (Sandbox Code Playgroud)

选项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
Run Code Online (Sandbox Code Playgroud)

因此,正如您从选项1选项2规范中可以看到的,这里的决定是关于是否使用隐式类型转换,这是在构造函数的帮助下完成的,或者是为每个我想要我的String类型的类型单独键入每个实用程序工作.

据我所知,使用第一种方法的好处是它更容易实现和维护.而第二种方法可能会产生更好的性能结果.

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

Val*_*nit 2

当将参数类型的实例传递给需要类类型的方法时,隐式构造函数用于创建类类型的实例。这种隐式转换是通过调用类的构造函数来完成的。

例如,运行与您的代码类似的代码:

#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.
}
Run Code Online (Sandbox Code Playgroud)

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

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

这是这样一个例子:

#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.
}
Run Code Online (Sandbox Code Playgroud)

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

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

  1. 该类的构造成本足够低,您不关心它是否是隐式构造的。
  2. std::string有些类在概念上与其参数相似,例如反映与const char*,因此隐式转换是有意义的,就像这里的情况一样。
  3. 如果禁用隐式转换,某些类的使用会变得更加不愉快。想想std::string每次要传递字符串文字时都必须显式构造 a 。

在某些情况下,隐式转换意义不大:

  1. 建设费用昂贵。
  2. 类在概念上与其论点非常不同。String考虑带有 the和 the 的示例int
  3. 施工可能会产生不良的副作用。例如,AnsiString类不应从 a 隐式构造UnicodeString,因为 Unicode 到 ANSI 的转换可能会丢失信息。

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