在C++中,struct和class之间的区别很小,基本上只有struct成员是默认的public,而class member是默认的private.
但是,每当我需要纯数据结构时,我仍然使用结构,例如:
struct Rectangle {
int width;
int height;
};
Run Code Online (Sandbox Code Playgroud)
我觉得使用非常方便:
Rectangle r;
r.width = 20;
r.height = 10;
Run Code Online (Sandbox Code Playgroud)
但是,数据结构来自过程编程,我正在进行面向对象的编程.将这个概念引入OO是一个坏主意吗?
我很清楚类和结构之间的区别,但是我很难权威地说这是否定义得很好:
// declare foo (struct)
struct foo;
// define foo (class)
class foo {
};
// instance of foo, claiming to be a struct again! Well defined?
struct foo bar;
// mixing class and struct like this upsets at least one compiler (names are mangled differently)
const foo& test() {
return bar;
}
int main() {
test();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果这是未定义的行为,有人可以指向权威(即ISO的章节和经文)参考的方向吗?
处理这个问题的编译器(Carbide 2.7)相对较旧,我尝试过的所有其他编译器对此都非常满意,但显然没有任何证据.
我的直觉是这应该是未定义的行为,但我找不到任何证实这一点,我很惊讶没有GCC版本或Comeau这么多警告它.
在诸如此类的情况下,在结构上使用类是否有任何优势?(注意:它只会保存变量,永远不会有函数)
class Foo {
private:
struct Pos { int x, y, z };
public:
Pos Position;
};
Run Code Online (Sandbox Code Playgroud)
与:
struct Foo {
struct Pos { int x, y, z } Pos;
};
Run Code Online (Sandbox Code Playgroud)
类似的问题:
我遇到一种我不理解的奇怪行为。因此,我在两个不同的cpp文件中定义了两个具有相同名称的不同类。我知道这不会在翻译单元的编译过程中引起任何错误,因为他们彼此之间并不了解。但是,链接器将这些文件链接在一起时,是否不应该抛出一些错误?
可能重复:
C++中struct和class之间有什么区别
我使用到想的只有 C++类之间的差异是私营的默认类成员访问修饰符和悠闲的出样-C的保证.
事实证明我错了,因为这段代码不能编译:
class { int value; } var = { 42 };
Run Code Online (Sandbox Code Playgroud)
这样做:
struct { int value; } var = { 42 };
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚为什么会有区别,但显然在Visual C++ 2008中:
错误C2552 ::
'var'无法使用初始化列表初始化非聚合
所以,是的,我会问多次重复的问题(希望没有重复的答案!):
当然,如果你发现我在其他问题上遗漏了一些东西,我可以随意关闭它 - 我当然可以.但我没有看到在任何答案中都讨论过这个问题,所以我想我会问.
使用a struct我们可以实现class:构造函数(可以修改/重载),析构函数(可以修改/重载),运算符重载,实例方法,静态方法,public/ private/ protected字段/方法的所有功能.
那为什么我们需要class呢?
注意:我不希望答案说明struct,字段/方法是public默认的.
它已经成熟并且是一个规范的参考问题,在C++结构和类中,在手动编写代码时几乎可以互换.
但是,如果我想链接到现有代码,如果我在原始代码之后将头重新声明为一个类,或者反之亦然,我可以期望它能够产生任何差异(例如,中断,鼻子恶魔等)产生的?
所以这种情况是被编译成一个结构(或类)的类型,而我则改变了头文件到其他声明,包括它在我的项目之前.
真实世界的用例是我用SWIG自动生成代码,根据是给定结构还是类,生成不同的输出; 我需要将其中一个更改为另一个以使其输出正确的界面.
这个例子在这里(Irrlicht,SVertexManipulator.h) - 给出:
struct IVertexManipulator
{
};
Run Code Online (Sandbox Code Playgroud)
我机械地重新声明它:
/*struct*/class IVertexManipulator
{public:
};
Run Code Online (Sandbox Code Playgroud)
原始库使用原始标题进行编译,不受影响.包装器代码使用修改后的表单生成,并使用它们进行编译.然后将这两个链接到同一个程序中以便一起工作.假设我对两个库使用完全相同的编译器.
这种事情是不确定的?"未定义",但预计会在现实编译器上工作?完全允许?
我正在做的其他类似的更改包括从参数中删除一些默认值(以防止歧义),以及从SWIG不可见类型的几个类中删除字段声明(这改变了类的结构,但我的推理是生成的代码应该需要该信息,仅链接到成员函数).再次,这会造成多大的破坏?
s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName/*="main"*/,
E_VERTEX_SHADER_TYPE vsCompileTarget/*=EVST_VS_1_1*/,
const c8* pixelShaderProgram=0,
...
Run Code Online (Sandbox Code Playgroud)
public:
//IIndexList *Indices;
Run Code Online (Sandbox Code Playgroud)
......等等.其他更改包括使用typedef替换某些模板参数类型并packed从某些结构中删除该属性.同样,如果更改的结构声明从未在机器代码中实际使用(仅生成链接到主库中的访问器函数的名称),似乎应该没有问题,但这是否可靠?这样的情况?
我有以下代码(涉及多个文件)...
//--- SomeInterface.h
struct SomeInterface
{
virtual void foo() = 0;
virtual ~SomeInterface(){}
};
//--- SomeInterfaceUser.h
#include <memory> //shared_ptr
class SomeInterface;
//NOTE: struct SomeInterface... causes linker error to go away...
class SomeInterfaceUser
{
public:
explicit SomeInterfaceUser(std::shared_ptr<SomeInterface> s);
};
//SomeInterfaceUser.cpp
#include "SomeInterfaceUser.h"
#include "SomeInterface.h"
SomeInterfaceUser::SomeInterfaceUser(std::shared_ptr<SomeInterface> s)
{
}
//SomerInterfaceUserInstantiator.cpp
#include "SomeInterfaceUser.h"
#include "SomeInterfaceImpl.h"
struct SomeInterfaceImpl : SomeInterface
{
virtual void foo(){}
};
void test()
{
SomeInterfaceUser x{std::make_shared<SomeInterfaceImpl>()};
}
Run Code Online (Sandbox Code Playgroud)
使用Visual C ++编译器,我得到一个链接器错误(LNK2019)。使用GCC 4.8.4并非如此。将前向声明类SomeInterface更改为struct SomeInterface可使链接器错误消失。我一直以为应该可以互换使用类/结构?SomeInterfaceUser的接口不应取决于SomeInterface是定义为类还是struct,不是吗?
这是Visual C ++错误吗?我找不到任何与此有关的东西。我怀疑将struct用作模板参数这一事实与它有关。
感谢您的帮助。
或者是吗?
面向对象的设计是否应该使用默认情况下公开成员数据的语言结构,如果有一个同样有用的结构可以正确隐藏数据成员?
编辑:其中一个响应者提到,如果没有不变量,可以使用结构.这是一个有趣的观察结果:结构是一种数据结构,即它包含相关数据.如果结构中的数据成员是相关的,那么总是存在不变量吗?
我正在制作国际象棋游戏,我希望有一系列作品.
如果我是对的,在Java中你可以拥有一个抽象Piece类并拥有King或Queen扩展该类.如果我做的阵列Piece的I可以放置一个King数组中的一块地方和Queen在另一个地方,因为这两个部分King和Queen延伸Piece.
有没有办法用C++中的结构做到这一点?