none
Переопределение класса C++ RRS feed

  • Вопрос

  • Здравствуйте, такой вопрос: есть два файла:

    1 файл:

    #include"iostream"
    class base{
    public:
    int i;
    };
    void test(base ob){

    std::cout<<"h"<<(ob.i=9);
    }

    2 файл:

    #include"iostream"
    using namespace std;
    class base{};
    void test(base ob);
    int main(){
    base ob;
    test(ob);
    system("pause");
    return 0;
    }

    При запуске программы выходит: h9. Соответственно два вопроса:

    1. Почему не было ошибки компоновки (переопределение типа)?

    2. Как удалось присвоить 9 члену "i", если в реализации для второго файла класс base вовсе такого члена не имеет?

    И вот ещё что примечательно: если в реализации base для второго файла создать член данных  (не важно как обозвать о главное чтобы тоже int) то при выполнении вылетает ошибка.

    Спасибо!



    13 апреля 2015 г. 22:35

Ответы

  • Здравствуйте. Во втором файле Вы определили другой класс (переопределения типа нет, т.к. файлы cpp компилируются независимо). В этом легко убедится, вычислив размер объекта ob в функциях main и test:

    // файл 1
    class base
    {
    public:
    	int i;
    };
    
    void test(base ob)
    {
    	cout << __FUNCTION__ << ": " << sizeof(ob) << endl;
    	cout << "h" << (ob.i = 9) << endl;
    }
    
    // файл 2
    class base
    {
    };
    
    void test(base ob);
    
    void main()
    {
    	base ob;
    	cout << __FUNCTION__ << ": " << sizeof(ob) << endl;
    	test(ob);
    }

    Далее, код функции test создан на основе первого определения класса и работает в уверенности, что поле i существует. Фактически же выполнение данной функции приводит к "порче" информации в стеке, т.к. test получила копию объекта второго класса (у которого поля i нет). Сделайте параметром test ссылку на base и получите ошибку времени выполнения.


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    14 апреля 2015 г. 11:11

Все ответы

  • Видимо class base{}; воспринимается как объявление внешнего класса а не определение. Если добавить в него что-нибудь, то он начинает воспринимать как определение и начинается конфликт.

    Хотя по идее так не должно быть, пустой класс должен быть полноценным типом размером в 1 байт, пусть и бесполезным.

    14 апреля 2015 г. 5:14
  • Здравствуйте. Во втором файле Вы определили другой класс (переопределения типа нет, т.к. файлы cpp компилируются независимо). В этом легко убедится, вычислив размер объекта ob в функциях main и test:

    // файл 1
    class base
    {
    public:
    	int i;
    };
    
    void test(base ob)
    {
    	cout << __FUNCTION__ << ": " << sizeof(ob) << endl;
    	cout << "h" << (ob.i = 9) << endl;
    }
    
    // файл 2
    class base
    {
    };
    
    void test(base ob);
    
    void main()
    {
    	base ob;
    	cout << __FUNCTION__ << ": " << sizeof(ob) << endl;
    	test(ob);
    }

    Далее, код функции test создан на основе первого определения класса и работает в уверенности, что поле i существует. Фактически же выполнение данной функции приводит к "порче" информации в стеке, т.к. test получила копию объекта второго класса (у которого поля i нет). Сделайте параметром test ссылку на base и получите ошибку времени выполнения.


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    14 апреля 2015 г. 11:11
  • Спасибо, Вам, большое за ответы на все мои "заковыристые" вопросы!)
    14 апреля 2015 г. 11:34
  • Да, не за что. Как тут выразился один из участников, такие вопросы - хорошая гимнастика для ума :)

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    14 апреля 2015 г. 11:41