重载operator和modifiyng字符串 [英] Overloading operator and modifiyng string

查看:136
本文介绍了重载operator和modifiyng字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习运算符过度编码。我已经创建了简单的类来测试它。

I am learning about operator overlaoding. I have created simple class to test it.

class Beer{
public:
   Beer(int oner , int twor , string name){
   this -> one = oner;
   this -> two = twor;
   this -> name = name;
   };
    int getOne(){

        return this -> one;
    };
    int getTwo(){

        return this -> two;
    };
    string getName(){
        return this -> name;
    };
    Beer operator + (const Beer &a)const {

        return Beer(5,two+a.two,"firstName");

    };
    Beer operator + (string a)const {

       this -> name =  this -> name +" "+a;

    };

private:

   int one;
   int two;
   string name;
};

我想弄明白,如何用重载的操作数来减少字符串。我的函数我声明了

I am trying to figure out , how to midify the string with overloaded operand. My function i declared

Beer operator + (string a)const {
      this -> name =  this -> name +" "+a;
};

抛出关于传递常量字符串的错误。

Throws error about passing const string.

我尝试使用

Beer operator + ( const string *a)const { 
       swap(this -> name , this -> name + " " + a);
       return *this;
    };

哪一个抱怨一个是cosnst字符串,第二个是基本字符串。

Which complained about one being cosnst string , and secon one being basic string.

这个想法很简单。

Beer one ( 5, 6, "one")
one + "two"

// one.name = "one two"

什么是正确的方法?

//与交换错误

error: no matching function for call to 'swap(const string&, std::basic_string<char>)'|

// erro with string

// erro with string

passing 'const string {aka const std::basic_string<char>}' as 'this' argument of 'std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(std::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' discards qualifiers [-fpermissive]|


推荐答案

注释:


  1. 不要包含整个 std 命名空间。你可能会遇到与你自己的代码讨厌的名字冲突。最多可以使用明确需要的符号,例如使用std :: string;

  1. Don't include the entire std namespace. You're likely to run into nasty name clashes with your own code. At most, use the symbols you need explicitly, e.g. using std::string;.

除非需要修改值的副本通过const引用的大对象,如 std :: string 。当你将一个参数声明为值类型 std :: string 时,你会收到一个字符串的副本,这很昂贵,除非你需要一个副本来修改你的函数。

Unless you need a copy of a value to modify, pass large objects like std::string by const reference. When you declare a parameter as having a value type std::string, you receive a copy of the string, and that's expensive unless you need a copy to modify inside of your function.

这是C ++标准的一个长期存在的问题:像这样的实现细节,应该与函数的用户无关,泄漏到接口函数的声明)。不过,当有一个副本是有意义的,让编译器给你一个,而不必键入太多。因此:

This is a long-standing problem with the C++ standard: an implementation detail like this, that should be irrelevant to the user of the function, leaks into the interface (the declaration of the function). Still, when having a copy makes sense, let the compiler give you one without having to type as much. Thus:

// prefer this
std::string fooize(std::string foo) {
  assert(foo.size() > 0);
  foo.insert(1, "foo");
  return foo;
}
// over this
std::string fooize(const std::string & bar) {
  assert(bar.size() > 0);
  auto foo = bar;
  foo.insert(1, "foo");
  return foo;
}


  • 使用初始化器列表,然后就不需要傻的名字体操(你有 oner twor 名称:

    Beer(int one, int two, const std::string & name) :
      one(one),
      two(two),
      name(name)
    {}
    


  • 声明只读访问器const:

  • Declare read-only accessors const:

    int getOne() const { return one; }
    


  • 通过const引用返回大的值,如字符串;用户代码很可能让编译器帮助自动生成副本:

  • Return large values like strings by const reference; the user code will likely have the compiler help out with making a copy when needed automatically:

    const std::string & getName() const { return name; }
    
    // use:
    Beer beer{0,0,""};
    std::cout << (beer.getName() + "!") << std::endl; // makes a copy of name as needed
    


  • + 取字符串,你应该返回一个新对象,不要修改 this

  • In the + operator taking a string, you're supposed to return a new object, not modify this. You pretty much should do it the way the other operator + you have did it.

    Beer operator +(const std::string & a) const {
      return Beer(one, two, name + " " + a);
    };
    


  • 如果要修改对象,您需要 =

    Beer & operator+=(const std::string & a) {
      name += " ";
      name += a;
      return *this;
    }
    


  • 即使你的类被设计为实验运算符,总是考虑操作员是否使生活更容易。例如,你的类有三个成员。它不是立即显而易见这些成员中的哪些将被操作,除非另外清楚从类的语义。更清楚的方法是使用 addToOne addToTwo appendToName ,例如,而不是运算符,或者简单地让用户通过setters设置成员,例如 setOne(int one){this-> one = one; } 。然后,用户只需执行 beer.setOne(beer.getOne()+ 2);

  • Even though your class was designed to experiment with operators, you should always consider whether the operators make life easier or not. For example, you class has three members. It's not immediately apparent which of these members would be operated on, unless it was otherwise clear from the class's semantics. It'd be much clearer to have methods named addToOne, addToTwo, and appendToName, for example, instead of operator(s), or simply letting the user set the member through setters, like setOne(int one) { this->one = one; }. The user would then simply do beer.setOne(beer.getOne() + 2);.

    考虑命名没有 get 前缀的getter,例如

    Consider naming getters without the get prefix, e.g.

    class Beer {
      int m_one;
    public int one() const { reeturn m_one; }
    };
    

    标准库以及 boost Qt 等大型库遵循此惯例,例如您有 std :: string :: size(),而不是 std :: string :: getSize()

    It's less typing for the user. The standard library, as well as large libraries like boost and Qt follow this convention, e.g. you have std::string::size(), not std::string::getSize(), etc.

    这篇关于重载operator和modifiyng字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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