sizeof получен уже из базы - PullRequest
0 голосов
/ 29 апреля 2010

возможно ли вернуть sizeof производный класс уже из базового класса / структуры?

imho размер класса является своего рода свойством, как вес человека. Но я не хочу писать одну и ту же функцию в каждом классе.

большое спасибо заранее
ой PS: так что код, чтобы сделать мой вопрос более понятным:

template <typename T>
struct StructBase {
    size_t size<T>(){
        return sizeof(T);
    }
};

struct MyStruct: public StructBase<MyStruct> {
    double d1;
    double d2;
    double d3;
    MyStruct(): d1(0), d2(0), d3(0){}
    //I do not want to do this here
    //size_t size(){ //return size<MyStruct> ;}
};

int main(void) {
   MyStruct m;
   std::cout << m.size(); //nop ?!?
}

Ответы [ 4 ]

2 голосов
/ 29 апреля 2010

Поскольку базовые классы не должны знать о производных от них классах (что может создать циклическую зависимость), метод базового класса не может даже знать, какие дополнительные поля были добавлены в производный класс. Более того, sizeof не может быть полиморфным - он работает только со статическими типами и структурами. Следовательно, нет смысла пытаться что-то вроде sizeof(*this).

Так что это не сработает.

Обновление: ну, теперь это совершенно другой вопрос. С шаблонами это может даже работать FWIW (у меня нет IDE, чтобы попробовать это). Но обратите внимание, что теперь у вас практически есть шаблонная функция с параметром типа, который может быть чем угодно - только для вас, программиста, только для производных классов. И в целом, я не вижу, что вы на самом деле выиграете с этим решением, что также может быть связано с отсутствием контекста.

1 голос
/ 29 апреля 2010
class A {
  int a;
}

class B : A {
 int b;
}

Размер B (2xint) в два раза больше размера A (1xint), sizeof относится не к объекту, а к типу. Я знаю, что вы хотите сделать, но полиморфизм работает только с объектами, а не с типами. Так что, если вы делаете sizeof(A) и ожидаете, что он вернет размер B, подумайте дважды, процессор не сможет узнать, что вы хотели получить размер B вместо A, поскольку они различны; -)

1 голос
/ 29 апреля 2010

Вы не можете перегрузить оператор sizeof. И я не уверен, что вы спрашиваете:

class A {
   int x, y;
};

тогда:

size_t n = sizeof( A );

дает вам размер класса А. Я не понимаю, откуда происходит деривация.

Редактировать: и относительно вашего расширенного вопроса, я не понимаю, почему вы не можете сказать:

MyStruct m;
std::cout << sizeof( m );

Обратите внимание, что размер не является таким же свойством, как вес - вес может изменяться и различается для разных экземпляров. Размер класса должен быть известен компилятору во время компиляции и никогда не может изменяться.

0 голосов
/ 03 мая 2010

Вот пример того, как это можно сделать:

template <typename T> 
struct StructBase { 
    unsigned int const size;
    StructBase<T>():size(sizeof(T)) { }
}; 

struct MyStruct: public StructBase<MyStruct> { 
    double d1; 
    double d2; 
    double d3; 
    MyStruct(): d1(0), d2(0), d3(0){} 
    //I do not want to do this here 
    //size_t size(){ //return size<MyStruct> ;} 
};

действительно, это очень просто, но есть один недостаток: размер каждой структуры, полученной из structBase, будет иметь еще одну переменную, и в зависимости от других переменных размер может быть значительно увеличен: в этом примере размер MyStruct составляет 24 байта без базового класса StructBase, но с базовым классом он составляет 32 байта. это то, что вы, возможно, не любите иметь в каждом случае.

С уважением К сожалению

...