簡體   English   中英

可以使用繼承來減少C ++中編譯代碼的大小嗎?

[英]Can inheritance be used to reduce the size of compiled code in C++?

我正在為一個基於Arduino的系統(即一個嵌入式系統)開發一個項目,並且擁有有限數量的ROM代碼。

我發現自己需要幾種不同類型的集合類(例如ListStackQueue )。 寫完這些后,我注意到除了使它們表現不同的功能(例如Add vs Push vs EnqueuePop 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引用相同的方法,盡管類型不同,因為BA的子類。 如果是這種情況,那么具有類似功能的類都從實現相似性的單個基類繼承將產生比使每個類單獨實現功能更少的編譯代碼,因為每個子類將使用相同的功能。

我提供的關於提出這個問題的情況的信息僅僅是背景,我知道這是否是任何編譯器的情況,而不僅僅是我正在使用的那個(我完全理解答案可能是“有可能是一些編譯器這樣做,但並非所有這些都“,這是一個完全可以接受的答案”。

我不能給出明確的答案,但我想分享我的發現。 實際上我並不像我預期的那樣容易衡量差異。 不要把代碼太嚴肅,我只是嘗試隨機的東西,看它是否有任何影響...

#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);
}

我必須再次檢查數字,但令我驚訝的是,與c風格的prinft相比,使用iostream時可執行文件更小。

當我用(g ++ 4.9.2)編譯它時

g++ main.cpp -Os -fno-exceptions -s

我得到了13.312 kB的可執行文件。 這與DERIVED的定義是否獨立無關。 但是,當我用它編譯它時

g++ main.cpp -Os -fno-exceptions

大小是43.549 kB。 再次獨立於DERIVED的定義與否。

我的結論是

  • 我的例子並不適合衡量差異
  • ...然而,試驗編譯器標志會產生巨大的差異,而繼承與否則沒什么區別
  • 我不會改變設計,以減少代碼大小。 編寫代碼,以便在需要從exe中擠出一些KB時,易於讀取,編寫和使用並使用編譯器標志(另請參見此處

寫一個單片容器來完成所有工作。

私下繼承它。 使用using將要公開的方法帶入視圖。

最多一些極短的方法將由編譯器為dtor / ctor創建。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM