简体   繁体   English

Const引用字段作为C ++类中的readonly属性

[英]Const reference field as readonly property in C++ class

Is it good to use a const reference field as a readonly getter in C++ classes? 在C ++类中使用const引用字段作为只读getter是否合适?

I mean, does this code meet good practices? 我的意思是,这段代码是否符合良好做法?

class check{
private:
    int _x;
public:
    const int& x = _x;
    void setX(int v){
        _x = v;
    }
};

It is working very much like C# properties, IMHO, and very easy and clean in class usage code: 它非常像C#属性,恕我直言,并且在类使用代码中非常简单和干净:

  check s;
  int i;
  std::cin >> i;
  s.setX(i);
  std::cout << s.x << '\n';
  s.setX(7);
  // s.x = i; // Error
  std::cout<<s.x<<'\n';

do this code meet good practices? 这段代码符合良好做法吗?

Not really, since it introduces unnecessary complexity and space overhead. 不是真的,因为它引入了不必要的复杂性和空间开销。

Moreover, you wouldn't be able to perform runtime checks and/or assertions, regardless of the value being accessed. 此外,无论访问的值如何,您都无法执行运行时检查和/或断言。

Furthermore, what happens with the lifetime and semantics? 此外,生命周期和语义会发生什么?

Try assigning one check in your code to another and see what happens. 尝试将代码中的一个check分配给另一个,看看会发生什么。 The assignment is ill-formed because the class is non-assignable. 分配不正确,因为该类是不可分配的。 You should provide a copy and move constructor to take care of the reference, so that it won't refer to the old object's data member. 您应该提供一个复制和移动构造函数来处理引用,这样它就不会引用旧对象的数据成员。

Better use _x directly and have a straightforward inline getter function. 最好直接使用_x并具有简单的内联getter功能。


PS: C#-like properties in native C++? PS: 原生C ++中的C#属性?

Generally, it is not a good practice. 一般来说,这不是一个好习惯。

imho, and very easy and clean in class usage code. imho,在课堂使用代码中非常简单和干净。

Why should that be clearer and easier? 为什么要更清楚,更容易?

  • You introduce another variable member (useless overhead). 你引入了另一个变量成员(无用的开销)。 (Generally, the reference will be implemented as an additional member pointer). (通常,引用将作为附加成员指针实现)。
  • It makes the code harder to maintain. 它使代码更难维护。 You are actually creating dependencies among variable members. 您实际上是在变量成员之间创建依赖关系。
  • It makes problem in the assignment and in the copy operations. 它在赋值和复制操作中产生问题。 How is copy operation supposed to work? 如何复制操作?

The "classic" approach is sound clearer by me, eg: “经典”的方法听起来更清晰,例如:

class Foo {
 public:
  void set_num(int value) noexcept { m_num = value; }
  int get_num() const noexcept { return m_num; }
  void set_string(std::string value) noexcept {
      m_str = std::move(value);
  }
  const std::string& get_string() const noexcept {
      return m_str;
  }
 private:
  int m_num;
  std::string m_str;
};

From a performances point of view, this approach should be preferred. 从性能的角度来看,这种方法应该是首选。

  • Timing complexity: call get_variable on an inline function does not introduce more overhead than your "reference approach". 时序复杂度: get_variable 函数上调用get_variable不会引入比“参考方法”更多的开销。 Moreover, it is highly optimizable by the compiler (because of straightforward of the code). 此外,它可以被编译器高度优化(因为代码简单)。
  • Space complexity: it does not introduce additional data member. 空间复杂性:它不会引入额外的数据成员。

What you propose is in general a bad idea: 你提出的建议总的来说是一个坏主意:

  • You can't implement the property by doing any processing (eg with a getter you can store co-ordinates using [x,y] and later decide to change the implementation to use [angle,radius] while keeping the same public interface). 您无法通过任何处理来实现该属性(例如,使用[x,y]可以存储坐标的getter,然后决定将实现更改为使用[angle,radius],同时保持相同的公共接口)。
  • Using a const member variable involves space overhead, and doesn't give you any performance advantage compared with an inline getter. 使用const成员变量涉及空间开销,与内联getter相比,不会给您带来任何性能优势。
  • It's not idiomatic. 这不是惯用的。
  • Once you've published your class, and other people start using it, you're stuck with it: it's too late to change it to use a method instead. 一旦你发表了你的课程,而其他人开始使用它,你就会坚持下去:现在改变它以使用方法为时已晚。

If your intention with properties is to make the code more succinct, you don't have to use the words "get" and "set" in your function names; 如果您对属性的意图是使代码更简洁,则不必在函数名中使用“get”和“set”; that's an old-fashioned practice. 这是一种老式的做法。 You can use the actual name of the "property" as the function name, and you can overload the getter and setter: 您可以使用“属性”的实际名称作为函数名称,并且可以重载getter和setter:

class Cheque {
public:
    int x() const {
        return x_;
    }
    Cheque & x(int newX) {
        x_ = newX;
        return *this;
    }
private:
    int x_;
}

// Usage:
// int amt = myCheque.x(1234);
// Cheque c = Cheque().x(123);

Returning *this as in the above code enables you to use method chaining ; 按照上面的代码返回*this ,可以使用方法链 ; a way of implementing the Fluent interface idiom. 一种实现Fluent界面习语的方法。

When C# compiles a propery it gets compiled into a getter and a setter function. 当C#编译一个属性时,它会被编译成一个getter和一个setter函数。

Here's some C# code that proves this fact: 以下是一些证明这一事实的C#代码:

using System;

namespace Reflect
{
    class Program
    {
        class X
        {
            public int Prop { get; set; }
        }

        static void Main(string[] args)
        {
            var type = typeof(X);
            foreach (var method in type.GetMethods())
            {
                Console.WriteLine(method.Name);
            }
            Console.ReadKey();
        }
    }
}

Your output should be: 你的输出应该是:

get_Prop
set_Prop
ToString
Equals
GetHashCode
GetType

get_Prop is the function that implements the getter. get_Prop是实现getter的函数。 set_Prop is the function that implements the setter. set_Prop是实现setter的函数。

So even if what you're doing looks similar, it's not the same at all. 所以,即使你所做的事情看起来很相似,也不一样。

Frankly almost everything you could do to try to emulate 'property syntax' in C++ will fall down in one way or another. 坦率地说,几乎所有你试图在C ++中模拟“属性语法”的东西都会以这种或那种方式落空。 Most solutions will either cost you memory or it'll have some limitation that makes it more cumbersome than useful. 大多数解决方案要么花费你的内存,要么它会有一些限制,使它比有用的更麻烦。

Just learn to live with getters and setters. 只要学会与吸气者和二传手一起生活。 Getters and setters are good practice . 吸气剂和制定者是很好的做法 They're short, they're simple, they're flexible, they're typically good candidates for inlining, everyone understands what they do et cetera. 它们很短,很简单,很灵活,通常很适合内联,每个人都理解他们做的事情等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM