当要访问的对象被多次封装时,如何正确使用setter?

oze*_*cik 5 c++ embedded getter setter misra

我经常与这个问题斗争,找不到任何明确的解决方案.我想我知道getter/setter的动机.

先前信息:

在实现真实数据时,通常将数据封装在多个层中.例如:

// 1st stage data types ------------------------------
struct Cartesian
{
    int32_t x;
    int32_t y;
    int32_t z;
}

struct GeoLocation
{
    double_t latitude;
    double_t longitude;
    int32_t altitude;
}

// 2nd stage data types ------------------------------
struct Drone
{
    Cartesian baseOffset; // m
    Cartesian velocity; // m/s
}

struct Plane
{
    GeoLocation location; // semicircle
    Cartesian velocity; // knots
}

// 3rd stage data types ------------------------------
struct Swarm
{
    Plane base;
    Drone member[10];
}
Run Code Online (Sandbox Code Playgroud)

在C++中,我使用类而不是结构(因为为什么不呢?).当Swarm[3].member[8].velocity.x通过某个通信信道接收到有关数据时,就会出现问题.意识到系统中可以有多个群.

需求:

根据MISRA C++规则,函数不能将非const引用返回给任何类成员,因为如果没有该类的权限/知识,则不应更改该成员.

题:

当我使用getter和setter时,我不能说" Swarm[3].member[8].velocity.x"; 相反,我可以用几种方式说这个:

1.这是不允许的,因为get()函数返回const引用,不能调用set().

Swarm[3].getMember(8).getVelocity().setX(5); (或set("X", 5))

2.此方法执行所有负担到群类.尽管对于谁调用Swarm类来说代码似乎更短,但是如果发生更改,代码和在后台进行维护的代码非常繁重.

Swarm[3].setMemberVelocity(8,X,5)

3.此方法介于两者之间,但问题在于您可能会牺牲效率,因为每次新数据到达时,您首先创建一个临时变量,获取它,填充并设置它.

Cartesian tempVelocity = Swarm[3].getMember(8).getVelocity();

tempVelocity.x = 5;

Swarm[3].setMemberVelocity(8, tempVelocity);

这三种方法中哪一种最好?或者我可以使用任何替代方案吗?

提前致谢.

Öö *_*iib 1

显然需要简单的旧数据、标准布局和可轻松复制。这种数据使得实现它的二进制布局变得更容易,它是可移植的并且与其他编程语言兼容。MISRA 要求使用关键字声明此类数据struct

作为副作用,这些数据还可以编写如下代码:

swarms[swarmNo].drones[droneNo].velocity.x = 5;
Run Code Online (Sandbox Code Playgroud)

这种深链导航仍然被认为是代码味道,它也被称为“火车残骸模式”。然而它至少没有任何不需要的get和臃肿set()打字。

所有其余数据都应遵循面向对象的原则。蜂群本身有责任通过命令无人机进行机动,而无人机本身有责任遵循(或拒绝)此类命令。没有任何东西能够简单地从外部突然设置某些东西的某些单独属性。

MISRA 要求使用关键字声明此类数据class。非静态数据成员应设为私有,并且公共成员函数不应返回这些成员的非常量句柄。