这个问题已经在c# /. net上下文中提出过了。

现在我想学习c++中结构体和类的区别。请讨论在OO设计中选择一种或另一种的技术差异以及原因。

我将从一个明显的区别开始:

如果没有指定public:或private:,结构体的成员默认为public;默认情况下,类的成员是私有的。

我敢肯定,在c++规范的晦涩角落里还会发现其他不同之处。


当前回答

c++的起源和与C的兼容性是值得记住的。

C语言有结构体,它没有封装的概念,所以一切都是公共的。

在采用面向对象的方法时,默认为public通常被认为是一个坏主意,所以在编写一种原生有利于OOP(你可以在C中做OO,但它不会帮助你)的C形式时,这是c++(最初是“C With Classes”)的想法,默认为private成员是有意义的。

另一方面,如果Stroustrup改变了struct的语义,使其成员默认为私有,那么就会破坏兼容性(随着标准的分歧,这种情况不再经常发生,但所有有效的C程序也是有效的c++程序,这对c++的立足点有很大影响)。

因此引入了一个新的关键字class,它与struct完全相似,但默认为private。

如果c++从零开始,没有历史,那么它可能只有一个这样的关键字。它也可能不会产生这样的影响。

一般来说,人们在做类似C语言中使用结构体的事情时,会倾向于使用结构体;公共成员,没有构造函数(只要它不在联合中,你可以在结构中有构造函数,就像类一样,但人们倾向于不这样做),没有虚方法,等等。因为语言既可以用来指导机器,也可以用来与阅读代码的人交流(否则我们就会坚持使用汇编和原始VM操作码),所以坚持使用它是个好主意。

其他回答

这只是一种惯例。可以创建结构来保存简单的数据,但稍后会随着成员函数和构造函数的添加而发展。另一方面,在struct中看到public: access之外的东西是不寻常的。

类的成员默认为private, struct的成员默认为public。

例如,程序1编译失败,程序2运行正常。

// Program 1
#include <stdio.h>
 
class Test {
    int x; // x is private
};

int main()
{
  Test t;
  t.x = 20; // compiler error because x is private
  getchar();
  return 0;
}
// Program 2
#include <stdio.h>
 
struct Test {
    int x; // x is public
};

int main()
{
  Test t;
  t.x = 20; // works fine because x is public
  getchar();
  return 0;
}

从类/结构派生结构时,基类/结构的默认访问说明符为public。派生类时,默认访问说明符为private。

例如,程序3编译失败,程序4工作正常。

// Program 3
#include <stdio.h>
 
class Base {
public:
    int x;
};
 
class Derived : Base { }; // is equivalent to class Derived : private Base {}
 
int main()
{
  Derived d;
  d.x = 20; // compiler error because inheritance is private
  getchar();
  return 0;
}
// Program 4
#include <stdio.h>
 
class Base {
public:
    int x;
};
 
struct Derived : Base { }; // is equivalent to struct Derived : public Base {}
 
int main()
{
  Derived d;
  d.x = 20; // works fine because inheritance is public
  getchar();
  return 0;
}

您可以将此作为何时使用struct或class的指导方针,https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx。

的实例,考虑定义一个结构体而不是类 类型小,通常寿命短或通常嵌入 其他对象。 避免定义结构体,除非该类型具有所有的 以下特点: 它在逻辑上代表一个值, 类似于基本类型(int, double等)。 它有一个实例 大小小于16字节。 它是不可变的。 它不必被装箱 频繁。

唯一的其他区别是类和结构的默认继承,不出意外,它们分别是私有和公共的。

另一件需要注意的事情是,如果你更新了一个有结构的遗留应用程序来使用类,你可能会遇到以下问题:

旧代码有结构,代码被清理,这些被更改为类。 然后将一两个虚函数添加到新更新的类中。

当虚函数在类中时,编译器会在内部添加额外的指针指向类数据,以指向函数。

这将如何打破旧的遗留代码是,如果在旧代码中的某个地方使用memfill将结构清除为零,这也将破坏额外的指针数据。