golgepapaz
23/06/2007, 05:27
yanlis anlasilmasini onlemek yada turkcesini bilemedegim icin bazi terimlerin ingilizcesini
kullanacagim o yuzden simdiden kusura bakmayin. Simdi durum soyle;
elimde oldukca buyuk bir header dosyasi var (6000 satirdan fazla-code generation) ve derleyip bir kutuphanede toplamam gereken 600 kusur tane cpp(yine code generation) dosyasi, bu header'i kendi headerlari araciligiyla #include ediyorlar. header dosyasinda yaklasik olarak 400 class tipi var.Bunlarin bir kismi asagida ki gibi class template'lerin instantiation typedefleri ,bazilari ise bunlarin kompozisyonundan olusan normal C++ siniflari...
template<typename T,Endianness Endian=LittleEndian>
class HLAgeneric :public DataElement
{
public:
typedef typename T valuetype;
HLAgeneric():_value(0){}
HLAgeneric(T val):_value(val)
{
if (HostEndianness!=Endian)
BYTESWAP(_value);
}
HLAgeneric(const HLAgeneric& rhs):_value(rhs._value)
{}
template<typename T2,Endianness Endian2>
HLAgeneric(const HLAgeneric<T2,Endian2>& rhs)
{
this->_value=rhs.getValue();
if(Endian!=HostEndianness)
{
BYTESWAP(_value);
}
}
HLAgeneric<T,Endian>& operator =(T rhs)
{
this->_value=rhs;
if (HostEndianness!=Endian)
BYTESWAP(_value);
return *this;
}
HLAgeneric& operator =(const HLAgeneric& rhs)
{
if (this == &rhs) return *this;
this->_value=rhs._value;
return *this;
}
template<typename T2,Endianness Endian2>
HLAgeneric<T,Endian>& operator =(const HLAgeneric<T2,Endian2>& rhs)
{
if ((void*)this == (void*)&rhs) return *this;
this->_value=rhs.getValue();
if(Endian!=HostEndianness)
{
BYTESWAP(_value);
}
return *this;
}
operator T() const {return getValue();}
virtual int getOctetBoundary() const {return sizeof(T);}
virtual void encode(ByteWrapper& byteWrapper)
{
byteWrapper.put<T>(_value);
}
......
};
yani genel olarak soyle bir yapisi var..
//BigHeader.h
--------------------
typedef HLAgeneric<unsigned char> HLAoctet;
typedef HLAgeneric<short int> HLAinteger16LE;
typedef HLAgeneric<short int,BigEndian> HLAinteger16BE;
typedef HLAgeneric<double,BigEndian> Double1;
class OMT13boolean : public HLAenum<HLAoctet>
{
public:
enum enumerators {
HLAfalse = 0,
HLAtrue = 1,
};
OMT13boolean();
OMT13boolean(const enumerators& rhs);
OMT13boolean& operator = (const enumerators& rhs);
};
struct WorldLocationStruct :public HLAfixedRecord
{
WorldLocationStruct();
WorldLocationStruct(const WorldLocationStruct& rhs);
Double1 X;
Double1 Y;
Double1 Z;
};
Anliyacaginiz gibi sinfilar oldukca basit holder siniflar.Ancak template'lerin dogasi geregi tanimlarini derleyicinin gormesi gerektiginden ve vazgecilmez standart kutuphane ile ve gerekli bir iki boost headeri yuzunden bu headeri sadece include etmek( icinden hic bir seyi kullanmamasina ragmen) object filein sizeni 800kb kadar arttiriyor,bu hesabi 650 cpp dosyasi icin yaparsak bayagi yuklu (yaklasik 800Mb-space optimized,releasemode )kadar object file olusuyor.Buraya kadar okey, sorun su ki linker en sonunda lib dosyasini olustururken tek yaptigi butun bu object file lari paketleyip bana sunmak, boylece elimde dagitamayacagim 800Mb lik bir kutuphane oluyor.
cpp dosyalarinin genel yapisi ise soyle;
classA.h
------------
#include "bigHeader.h"
class A{
public:
const Double1 & getSomeAttribute();
void setSomeAttribute(const Double1& val);
private:
Double1 someAttribute_;
};
classA.cpp
----------
#include "classA.h"
//class A gerceklemesi
classB.h
---------
#include "classA.h"
class B: public A{
public:
void setSomeAttribute(...);
... getSomeAttrubte();
private:
WorldLocationStruct someAttribute_;
...
};
classB.cpp
----------
#include "classB.h"
//class B gerceklemesi
ve boylece surup guduyor, eminim anladiniz.Bu durumda her bir cpp dosyasi ayri olarak bu headeri include ettiginden icindeki linkler olusuyor, ama linkerin bunlari olusturuken yok etmesi gerekmiyr mu? yok etmesi icin ne yapabilirim, header file kucultsem yada ayri dosyalar bolsem(vakit alici), object sizelarim kuculurmu?DLL yapmanin faydasi olur mu? class B de class A dan cok az miktarda ekstra kod icermesine ragmen niye aralarinda 300 kb lik bir fark oluyor.. Olasi fikirleriniz icin simdiden tesekkur ederim
Not: Derleyici olarak VC7.1 kullaniyorum.
kullanacagim o yuzden simdiden kusura bakmayin. Simdi durum soyle;
elimde oldukca buyuk bir header dosyasi var (6000 satirdan fazla-code generation) ve derleyip bir kutuphanede toplamam gereken 600 kusur tane cpp(yine code generation) dosyasi, bu header'i kendi headerlari araciligiyla #include ediyorlar. header dosyasinda yaklasik olarak 400 class tipi var.Bunlarin bir kismi asagida ki gibi class template'lerin instantiation typedefleri ,bazilari ise bunlarin kompozisyonundan olusan normal C++ siniflari...
template<typename T,Endianness Endian=LittleEndian>
class HLAgeneric :public DataElement
{
public:
typedef typename T valuetype;
HLAgeneric():_value(0){}
HLAgeneric(T val):_value(val)
{
if (HostEndianness!=Endian)
BYTESWAP(_value);
}
HLAgeneric(const HLAgeneric& rhs):_value(rhs._value)
{}
template<typename T2,Endianness Endian2>
HLAgeneric(const HLAgeneric<T2,Endian2>& rhs)
{
this->_value=rhs.getValue();
if(Endian!=HostEndianness)
{
BYTESWAP(_value);
}
}
HLAgeneric<T,Endian>& operator =(T rhs)
{
this->_value=rhs;
if (HostEndianness!=Endian)
BYTESWAP(_value);
return *this;
}
HLAgeneric& operator =(const HLAgeneric& rhs)
{
if (this == &rhs) return *this;
this->_value=rhs._value;
return *this;
}
template<typename T2,Endianness Endian2>
HLAgeneric<T,Endian>& operator =(const HLAgeneric<T2,Endian2>& rhs)
{
if ((void*)this == (void*)&rhs) return *this;
this->_value=rhs.getValue();
if(Endian!=HostEndianness)
{
BYTESWAP(_value);
}
return *this;
}
operator T() const {return getValue();}
virtual int getOctetBoundary() const {return sizeof(T);}
virtual void encode(ByteWrapper& byteWrapper)
{
byteWrapper.put<T>(_value);
}
......
};
yani genel olarak soyle bir yapisi var..
//BigHeader.h
--------------------
typedef HLAgeneric<unsigned char> HLAoctet;
typedef HLAgeneric<short int> HLAinteger16LE;
typedef HLAgeneric<short int,BigEndian> HLAinteger16BE;
typedef HLAgeneric<double,BigEndian> Double1;
class OMT13boolean : public HLAenum<HLAoctet>
{
public:
enum enumerators {
HLAfalse = 0,
HLAtrue = 1,
};
OMT13boolean();
OMT13boolean(const enumerators& rhs);
OMT13boolean& operator = (const enumerators& rhs);
};
struct WorldLocationStruct :public HLAfixedRecord
{
WorldLocationStruct();
WorldLocationStruct(const WorldLocationStruct& rhs);
Double1 X;
Double1 Y;
Double1 Z;
};
Anliyacaginiz gibi sinfilar oldukca basit holder siniflar.Ancak template'lerin dogasi geregi tanimlarini derleyicinin gormesi gerektiginden ve vazgecilmez standart kutuphane ile ve gerekli bir iki boost headeri yuzunden bu headeri sadece include etmek( icinden hic bir seyi kullanmamasina ragmen) object filein sizeni 800kb kadar arttiriyor,bu hesabi 650 cpp dosyasi icin yaparsak bayagi yuklu (yaklasik 800Mb-space optimized,releasemode )kadar object file olusuyor.Buraya kadar okey, sorun su ki linker en sonunda lib dosyasini olustururken tek yaptigi butun bu object file lari paketleyip bana sunmak, boylece elimde dagitamayacagim 800Mb lik bir kutuphane oluyor.
cpp dosyalarinin genel yapisi ise soyle;
classA.h
------------
#include "bigHeader.h"
class A{
public:
const Double1 & getSomeAttribute();
void setSomeAttribute(const Double1& val);
private:
Double1 someAttribute_;
};
classA.cpp
----------
#include "classA.h"
//class A gerceklemesi
classB.h
---------
#include "classA.h"
class B: public A{
public:
void setSomeAttribute(...);
... getSomeAttrubte();
private:
WorldLocationStruct someAttribute_;
...
};
classB.cpp
----------
#include "classB.h"
//class B gerceklemesi
ve boylece surup guduyor, eminim anladiniz.Bu durumda her bir cpp dosyasi ayri olarak bu headeri include ettiginden icindeki linkler olusuyor, ama linkerin bunlari olusturuken yok etmesi gerekmiyr mu? yok etmesi icin ne yapabilirim, header file kucultsem yada ayri dosyalar bolsem(vakit alici), object sizelarim kuculurmu?DLL yapmanin faydasi olur mu? class B de class A dan cok az miktarda ekstra kod icermesine ragmen niye aralarinda 300 kb lik bir fark oluyor.. Olasi fikirleriniz icin simdiden tesekkur ederim
Not: Derleyici olarak VC7.1 kullaniyorum.