私はArduinoベースのシステム(つまり組み込みシステム)のプロジェクトに取り組んでおり、コードが存在するためのROMの量が限られています。
私は自分自身のコレクションクラス(例えば、いくつかの異なるタイプを必要と発見しましたList
、Stack
、Queue
)。これらを書いた後、動作を変える機能(Add
vs Push
vs Enqueue
、Pop
vsなどDequeue
)を除いて、多くの共通機能を共有していることに気付きました(たとえば、まったく同じフィールドを持っています)。
これは、他のクラスのすべての共通機能を含む基本クラスを作成し(それを呼びましょうCollection
)、他のクラスにそれを継承させ、異なる機能のみを実装させるとしたら、そうなるだろうと思いました。コンパイルされたコードが少なくなりますか?
子クラスはすべて親の共通関数の実装を参照できるため、そうなると思いますが、間違っている可能性があるため、この変更を試みる前に質問したいと思います。
さて、人々は誤解しているように見えるので、これをさらに明確にするために、これらの架空のクラスを検討してください。
class A
{
protected:
int value;
public:
void assign(int other)
{
this->value = other;
}
}
class B : public A
{
public:
void assignAdd5(int other)
{
this->value = other + 5;
}
}
そして、コード:
A a = A();
B b = B();
a.assign(4);
b.assign(4);
はのサブクラスであるassign
ため、タイプが異なるにもかかわらず、両方の場合で同じメソッド(したがって、同じコンパイル済みコードブロック)を参照することを期待しています。この場合、類似した機能を持つクラスをすべて単一の基本クラスから継承して類似性を実装すると、各子クラスが同じ関数を使用するため、各クラスに機能を個別に実装させるよりもコンパイルされたコードが少なくなります。B
A
この質問を引き起こした状況に関して私が提供した情報は単なる背景であり、これが私が使用しているコンパイラだけでなく、どのコンパイラにも当てはまるかどうかにあります(そして答えは「コンパイラーはこれを行いますが、すべてが行うわけではありません」、そしてそれは完全に受け入れられる答えです)。
明確な答えは出せませんが、私の発見を共有したいと思います。実際、私は思ったほど違いを測定するのは簡単ではありません。コードをあまり真剣に受け止めないでください、私はそれが影響を与えるかどうかを確認するためにランダムなものを試していました...
#include <iostream>
#define DERIVED
#define BASE_STUFF int a,b,c,d,e,f,g,h,i,k,m,n,o,p,q,r,s,t,u,v,w,x,y,z; \
double foo1(int x){return x;} \
double foo2(int x){return x;} \
double foo3(int x){return x;} \
double foo4(int x){return x;} \
Base* foo5(Base* x){return x;} \
FPTR foo5(FPTR a,FPTR b,FPTR c){return a;}
typedef double (*FPTR)(int,int,double);
struct Base { BASE_STUFF };
#ifdef DERIVED
struct Derived : Base{double a0,a1,a2,a3,a4,a5,a6,a7;};
#endif
#ifndef DERIVED
struct Derived {
double a0,a1,a2,a3,a4,a5,a6,a7;
BASE_STUFF
};
#endif
int main(int argc, char *argv[])
{
Base b;
b.x = 1;
std::cout << b.foo1(b.x);
std::cout << b.foo5(&b)->foo2(b.a);
Derived n;
n.a0 = 2;
std::cout << n.foo1(n.a0);
}
番号をもう一度確認する必要がありますが、驚いたことに、iostream
sを使用した場合の実行可能ファイルはc-styleと比較して小さかったprinft
。
これを(g ++ 4.9.2)でコンパイルすると
g++ main.cpp -Os -fno-exceptions -s
13.312kBの実行可能ファイルを取得します。そして、それはDERIVED
定義されているかどうかとは無関係です。しかし、私がそれをコンパイルすると
g++ main.cpp -Os -fno-exceptions
サイズは43.549kBです。再びDERIVED
定義されているかどうかに関係なく。
私の結論は
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加