多少功能是“可接受的”对于C ++结构? [英] How much functionality is "acceptable" for a C++ struct?

查看:108
本文介绍了多少功能是“可接受的”对于C ++结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我知道C ++中的结构和类之间没有什么区别,但很多人包括我使用一个结构或类来显示意向结构,用于分组普通旧数据和具有有意义操作的封装数据的类。



现在,你开始认为一个东西不只是一个结构了,应该成为一个类吗?



对于结构体我认为是合理的:


  1. 只有简单初始化代码的构造函数。

  2. 序列化代码,如流插入/ $ b

我不太确定,但可能会这样做:


  1. 比较运算符

  2. 简单的转换函数 - 例如在从外部来源接收数据后交换所有成员的字节。

我不认为结构应该有:


  1. 动态内存分配。

  2. 破坏者。

  3. 复杂的成员函数。



另外,将类实例作为struct的成员是合理的吗?例如

  class C {private:int hiddenData; public:void DoSomething();}; 

struct S {int a;浮动b C c; };

S s; s.c.DoSomething();

记住,我不是关于你可以用C ++做什么,

解决方案



< Class vs. struct



使用class或struct关键字与感觉在读者身上产生。从技术上讲,它们是等效的,但如果结构体用于POD和C-struct类型和其他类的类,则可读性更好。



基本的东西应该放在C ++结构中:构造函数初始化数据(我不喜欢使用memset,如果POD演变成不同的东西,它可以后退)或构造从其他类型,但不是复制构造函数。



如果您需要定义复制构造函数或赋值运算符,因为编译器生成的不够好,请将其作为类。



对于将传递给STL算法和模板元编程的函子来说,通常使用structs,如

  struct square_int {
int operator()(int value)
{
返回值* value;
}
};
std :: transform(v.begin(),v.end(),v.begin(),square_int());

  //我的头顶部
模板< typename T>
struct is_pointer {enum {value = false}};

template< typename T>
struct is_pointer< T *> {enum {value = true}};

会员方法与自由功能



除了我之前所说的,这不会增加别人已经回答的,我想把一些焦点放在你的评论在你的帖子,作为比较运算符等的其他类型的函数。 / p>

运算符意味着对称(比较,算术),插入和删除运算符和转换通常更好地实现为自由函数,无论你声明它是一个类, struct。



对称运算符(对于数据类型)如果实现为成员函数,则不是对称的。查找规则不会投射左侧调用成员函数,但它将应用相同的转换以匹配自由函数。

  //自由函数的对称示例,其中方法将是不对称的
int main()
{
std :: string(Hello)+world // compiles as free / member function
Hello+ std :: string(world); //使用自由函数编译,失败,成员函数定义为+
}

上面的代码,如果operator +是std :: string的成员方法,编译器将无法编译,因为它无法将const char * literal转换为std :: string以使用成员方法。



从流中插入和提取必须始终作为自由函数实现,因为流始终是操作的左侧。



保持转换为自由函数解耦两种不同类型。如果A和A'可以转换成另一个,并且你决定实现变换作为A的成员,那么A必须知道A',A的所有使用将取决于A'是否使用它。如果将变换定义为自由函数,则A不包含A',两个类/ struct之间的耦合将更小。这同样适用于网络,序列化和反序列化的转换。当你在class / struct中实现它们时,你强迫所有用户知道这些变换。


My first post so please go easy on me!

I know that there's no real difference between structs and classes in C++, but a lot of people including me use a struct or class to show intent - structs for grouping "plain old data" and classes for encapsulated data that has meaningful operations.

Now, that's fine but at what point do you start to think that something isn't just a struct anymore and should become a class?

Things I think are reasonable for structs to have:

  1. constructors with simple initialisation code only.
  2. serialization code such as stream insertion / extraction operators.

Things I'm not so sure about, but would probably do:

  1. comparison operators
  2. Simple transformation functions - for example byteswapping all the members after receiving data from an external source.

I don't think structs should have:

  1. dynamic memory allocation.
  2. destructor.
  3. complex member functions.

Where do the boundaries lie???

Also, is it reasonable to have class instances as members of a struct? e.g.

class C {private: int hiddenData; public: void DoSomething();};

struct S {int a; float b; C c; };

S s; s.c.DoSomething();

Remember, I'm not on about what you CAN do with C++, I'm interested in what you SHOULD do when designing good software.

Thoughts?

解决方案

Class vs. struct

Using class or struct keyword is a matter of taste together with the 'feeling' it produces on the reader. Technically they are equivalent, but readability is better if structs are used for PODs and C-struct types and classes for anything else.

Basic things that should go in a C++ struct: constructor that initializes the data (I dislike using memset, and it can later bite back if the POD evolves into something different) or construction from other types but not copy constructor.

If you need to define a copy constructor or assignment operator because the compiler generated is not good enough, make it a class.

It is common to use structs also for functors that will be passed to STL algorithms and template metaprogramming, as in

struct square_int {
   int operator()( int value )
   {
      return value*value;
   }
};
std::transform( v.begin(), v.end(), v.begin(), square_int() );

or

// off the top of my head
template <typename T>
struct is_pointer { enum { value = false } };

template <typename T>
struct is_pointer<T*> { enum { value = true } };

Member methods vs. free functions

Besides what I have said before, that do not add to what others already answered, I wanted to put some focus on other types of functions that you comment in your post, as comparison operators and the like.

Operators that are meant to be symmetric (comparison, arithmetic), insertion and deletion operators and transformations are usually better implemented as free functions regardless of whether you declare it as a class or struct.

Symmetric operators (with regard to data types) are not symmetric if they are implemented as member functions. The lookup rules won't cast the left hand side to call a member function, but it will apply the same cast to match a free function.

   // Example of symmetry with free functions where method would be asymmetric
   int main()
   {
      std::string( "Hello " ) + "world"; // compiles as free / member function
      "Hello " + std::string( "world" ); // compiles with free function, fails with member function definition of +
   }

In the code above, if operator+ were a member method of std::string the compiler would fail to compile as it cannot cast the const char* literal into a std::string to use the member method.

Insertion and extraction from streams must always be implemented as free functions as the stream is always the left hand side of the operation.

Keeping transformations as free functions decouple the two different types. If A and A' can be converted into one another and you decide to implement transformations as members of A, then A must know A' and all uses of A will depend on A' whether you use it or not. If you define the transformation as a free function, A is complete without A' and the coupling between the two classes/structs will be smaller. The same goes for transformations to/from network, serialization and deserialization. When you implement them inside the class/struct you are forcing all users to know about those transforms.

这篇关于多少功能是“可接受的”对于C ++结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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