【问题标题】:Is it fine to replace an array with hierarchal structures and classes?用层次结构和类替换数组可以吗?
【发布时间】:2018-06-19 04:33:51
【问题描述】:

在我的实现中,我应该使用一个长数组,但我对数组的问题是它的索引对我来说没有多大意义。相反,我想使用分层类。但是,有时我需要以批量方式处理它们,例如在计算差异和导数或平均值时。

所有成员都是double,看起来对齐没有任何问题。下面是一个示例。这个例子显然工作正常。

我的问题是这种编程结构是否容易在不同的编译器或系统上失败?

#include <iostream>

class Room
{
public:
    double size;
    double temperature;
    double humidity;
    double oxigen_level;
    // etc
};

class Kitchen
{
public:
    double fan_speed;
    double temperature;
};

class Building // a hierarchal class
{
public:
    Room rooms[5];
    double distance;
    Kitchen kitchen;
};

Building diff(
    const Building &b1,
    const Building &b2) // treat as an array
{
    Building r=b2;
    double *p1=(double *)&b1;
    double *pr=(double *)&r;
    for(int i=0;i*sizeof(double)<sizeof(Building);i++)
        pr[i]-=p1[i];
    return r;
}

int main()
{
    Building b1,b2,delta;
    b1.rooms[3].humidity=0.44;
    b2.rooms[3].humidity=0.43;
    delta=diff(b1,b2);
    std::cout
        <<"diff: "
        <<delta.rooms[3].humidity
        <<std::endl;
    return 0;
}

【问题讨论】:

标签: c++ arrays class pointers


【解决方案1】:

您在diff 中所做的事情是一场噩梦。 如果您要进行这样的强制转换,最好为变量坚持使用普通数组。

但我会利用您使用结构的想法来帮助您进行计算。

将类作为数组的包装器。 然后代替变量,让它们成为函数(double size() {... })。 在计算中使用这些函数。

像往常一样,总是在过早优化之前进行测量。


编辑:

这是一场噩梦,因为类型是建立起来的,而不是编译器被欺骗去做其他事情。使用“假定的”底层结构,但它不必像人们期望的那样。

这是我要做的一个版本。

更好吗?与主要示例相比,它具有更少的汇编指令(75 对 86)。它具有读者可见的预期逻辑。它很容易调试。 ...

必须对这两个示例进行基准测试。不过我觉得差别不大。

编辑:实际上存在速度差异。下面的代码在 GCC、Clang 和 MSVC 上的运行速度比主示例中的代码要快。

Quick Bench Benchmark

Compiler Explorer example

#include <iostream>

class Room
{
public:
    double size{};
    double temperature{};
    double humidity{};
    double oxigen_level{};
    // etc
    Room& operator-=( const Room& r )
    {
        size -= r.size;
        temperature -= r.temperature;
        humidity -= r.humidity;
        oxigen_level -= r.oxigen_level;

        return *this;
    }
};

class Kitchen
{
public:
    double fan_speed{};
    double temperature{};

    Kitchen& operator-=( const Kitchen& k )
    {
        fan_speed -= k.fan_speed;
        temperature -= k.temperature;

        return *this;
    }
};

class Building // a hierarchal class
{
public:
    static const int room_count{5};

    Room    rooms[ room_count ];
    double  distance{};
    Kitchen kitchen;

    Building operator-( const Building& b )
    {
        Building ret = *this;

        for ( int i = 0; i < room_count; i++ )
            ret.rooms[ i ] -= b.rooms[ i ];

        ret.distance -= b.distance;
        ret.kitchen -= b.kitchen;

        return ret;
    }
};    
int main()
{
    Building b1,b2,delta;
    b1.rooms[3].humidity=0.44;
    b2.rooms[3].humidity=0.43;
    delta=b1-b2;//diff(b1,b2);
    std::cout
        <<"diff: "
        <<delta.rooms[3].humidity
        <<std::endl;
    return 0;
}

【讨论】:

  • 为什么这是一场噩梦?所有成员都应该是double,我们接受这是事实。这些类应该是自动创建的,而不是由程序员创建的,所以如果这就是你的意思,那么就没有犯错的机会。没有开销对我来说非常重要,因为程序必须尽可能快。通过使用函数,如果你的意思是this,我之前尝试过这种方法,当类变大时会很头疼。失控!
  • 我认为它与指针无关。但我确实认为优化已经减少了。
  • 其实我想说的不同:使用这段代码,优化器会找到更多优化它的方法。
  • 这是一个很好的设计,除了冗长的操作符,每次上课都必须更新。但至少这符合标准。
  • @ar2015 如果您更改数据的结构,为什么您不必更改数据的使用位置?在您之前的设计中,您必须找到所有一起使用数据的地方
猜你喜欢
  • 1970-01-01
  • 2023-03-20
  • 2017-04-22
  • 2015-07-16
  • 1970-01-01
  • 2012-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多