Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Пара вопросов по С++

2.2K
18 марта 2007 года
e1vin
153 / / 04.06.2006
Пишу программулину ( какую не скажу :) ) и возникло пара вопросов:

1. Хочу разнести по разным файлам все объявления классов и функций. Делаю файлы main.cpp ( основные функции ) и classes.cpp ( мои классы целиком, со всеми методами и свойствами ). В main.cpp добавляю строчку #include "classes.cpp", но компилятор начинает ругаться на двойные описания функций ( multiple definitions ). Что за ерунда?

Куда девать общие для всей программы именованные константы ( #define FUNCTION_ERROR 1 и т.д. ) ?

2. Не могу понять ничего по отношению с классами.

Есть класс
class classA
{
int x;
public:
classA ( int a ) { x = a; }
};

и класс
{
class classB
{
classA x [ 8 ];
...
};

Как мне передать конструктору каждого объекта в массиве x нужные значения ( в каждом экземпляре класса classB они изначально должны инициализироваться одними и теми же значениями, например, 0, 1, 2, 3, 4, ... ) изнутри класса classB?
361
18 марта 2007 года
Odissey_
661 / / 19.09.2006
По поводу первого можешь глянуть ссылки о страуструпе в этой странной дискусии.
По поводу второго, =) честно говоря приходит в голову только следующее решение

Код:
#include <stdio.h>

class A
{
    int x;
public:
    A(): x(0){}  
    A(int _x) : x(_x) {}
    void setX(int _x){x = _x;}
    int printX(void){printf("%d\n",x);}
};

class Bclass
{
    A * arrayA;
    public:      
      Bclass()
              {
                      arrayA = new A[3];
                      for (int i = 0; i<3; i++)
                             arrayA.setX(i);
              }
   void print_arrayA()
        {
             for (int i = 0; i<3; i++)
                 arrayA.printX();
        }
};

int main()
{
    Bclass b;
    b.print_arrayA();
    return 0;
}


Хотя решение вообщем то сомнительное, придется создавать массив в каждом констуркторе, а не только в констуркторе по умолчанию(или вызывать его во всех остальных) .. но пока в голову ничего другого не приходит =(
63
18 марта 2007 года
Zorkus
2.6K / / 04.11.2006
Цитата: e1vin
Пишу программулину ( какую не скажу :) ) и возникло пара вопросов:

1. Хочу разнести по разным файлам все объявления классов и функций. Делаю файлы main.cpp ( основные функции ) и classes.cpp ( мои классы целиком, со всеми методами и свойствами ). В main.cpp добавляю строчку #include "classes.cpp", но компилятор начинает ругаться на двойные описания функций ( multiple definitions ). Что за ерунда?


Лучше бы каждый класс разбивать на два файла - *.cpp и *.h, и в заголовочных писать:

 
Код:
#ifndef _MegaHeader_
#define _MegaHeader_
*** // code
#endif

А еще дай куски файлов (особенно куски, где в main.cpp используешь классы), и точный текст ошибки.
Цитата: e1vin

Куда девать общие для всей программы именованные константы ( #define FUNCTION_ERROR 1 и т.д. ) ?


Создай отдельный абстрактный класс, и в нем определи статические константы.

Цитата: e1vin
2. Не могу понять ничего по отношению с классами.
Есть класс

class classA
{
int x;
public:
classA ( int a ) { x = a; }
};

и класс
{
class classB
{
classA x [ 8 ];
...
};

Как мне передать конструктору каждого объекта в массиве x нужные значения ( в каждом экземпляре класса classB они изначально должны инициализироваться одними и теми же значениями, например, 0, 1, 2, 3, 4, ... ) изнутри класса classB?


Код:
#include <iostream>
#include <vector>
#include <cstdlib>

using namespace std;

class classA
{
int x;
public:
    classA(){};
classA (int a) { x = a; };
void print() { cout << x;}
};


class classB
{
public:
    classA ar[2];
    classB()
    {
        ar[0] = classA(1);
        ar[1] = classA(3);
    };

};

int main()
{
    classB a;
    a.ar[0].print();
    return 0;
   
}
2.2K
18 марта 2007 года
e1vin
153 / / 04.06.2006
Цитата: Zorkus
Лучше бы каждый класс разбивать на два файла - *.cpp и *.h, и в заголовочных писать:
 
Код:
#ifndef _MegaHeader_
#define _MegaHeader_
*** // code
#endif

А еще дай куски файлов (особенно куски, где в main.cpp используешь классы), и точный текст ошибки.

Создай отдельный абстрактный класс, и в нем определи статические константы.



С этой "проблемой" я уже разобрался, все констаты вынес в файл constants.h и прицепил к каждому файлу #include "constants.h".

Классы тоже вынес, но в classes.h. Все заработало сразу.

Интересно только почему файл должен быть заголовком, не могу я разве в .cpp запихать все свои классы и, включив его в файлы где эти классы требуются, пользоваться ими?

Цитата:

Код:
#include <iostream>
#include <vector>
#include <cstdlib>

using namespace std;

class classA
{
int x;
public:
    classA(){};
classA (int a) { x = a; };
void print() { cout << x;}
};


class classB
{
public:
    classA ar[2];
    classB()
    {
        ar[0] = classA(1);
        ar[1] = classA(3);
    };

};

int main()
{
    classB a;
    a.ar[0].print();
    return 0;
   
}



Сейчас дам полное описание проблемы:

Компилятор mingw32, среда CodeBlocks.

Вот кусок кода:

Код:
#include <iostream>
using namespace std;

class classA
{
    int x, y;
public:
    classA ( int a, int b )
    {
        x = a;
        y = b;
        cout << "Construction of classA object" << endl;
    }
    void showxy () { cout << x << ' ' << y << endl; }
};

class classB
{
    classA ar [ 8 ];
public:
    void get_array ();
    classB () { cout << "Construction of classB object" << endl; }
};

    void classB::get_array ()
    {
        int i;

        for ( i = 0; i < 8; i ++ )
        {
            ar [ i ].showxy ();
        }
    }

int main()
{
    classB mas;

    mas.get_array ();

    return 0;
}


Когда я пытаюсь скомпилировать программу в таком виде, компилятор вполне оправданно ругается:

"error: no matching function for call to 'classA::classA()"
"note: candidates are: classA::classA (const classA&)"
"note: classA::classA (int, int)"

Если строчку "classA ar [ 8 ];" заменить на
Код:
classA ar [ 8 ] =
    {
        ( 0, 1 ),
        ( 0, 2 ),
        ( 0, 3 ),
        ( 0, 4 ),
        ( 0, 5 ),
        ( 0, 6 ),
        ( 0, 7 ),
        ( 0, 8 )
    };


компилятор тоже ругается:

"error: a brace-enclosed initializer is not allower here berfore '{' token"
"error: ISO C++ forbids initialization of member 'ar'"
"error: making 'ar' static"
"error: invalid in-class initialization of static data member of non-integral type 'classA[8]'"

Что мне понятно, но уже хуже. Почему так?

Если то же самое заменить на
Код:
classA ar [ 8 ] =
    {
        classA ( 0, 1 ),
        classA ( 0, 2 ),
        classA ( 0, 3 ),
        classA ( 0, 4 ),
        classA ( 0, 5 ),
        classA ( 0, 6 ),
        classA ( 0, 7 ),
        classA ( 0, 8 )
    };


то ничего не меняется.

Так как же все-таки мне передать параметры конструктору каждого объекта в массиве, который является членом другого класса?
361
18 марта 2007 года
Odissey_
661 / / 19.09.2006
Цитата:
Что мне понятно, но уже хуже. Почему так?



Дело в том , что в C++ отсутствует возможность инициализации нестатического константного массива-члена класса.
Так что используй вариант предложеный мной или Zorkus`ом

2.2K
19 марта 2007 года
e1vin
153 / / 04.06.2006
Спасибо, пришлось делать так, как вы рекомендовали.
Конечно немного кривовато, но бог с ним.

Вопрос еще такой:
как уменьшить размер итогового .exe? Использую компилятор mingw32 версии 3.4.4. Обычная почти пустая программа с одним cout'ом занимает в итоге 450 с лишним килобайт. Эмпирическим путем удалось установить, что такой размер из-за включения <iostream>, заменив который на <cstdio>, например, программа получилась уже 15 кб.

Как бы это преодолеть? Не хотелось бы отказываться от ввода/вывода в стиле С++, но файл хочется поменьше.
63
19 марта 2007 года
Zorkus
2.6K / / 04.11.2006
Цитата: e1vin

Вопрос еще такой:
как уменьшить размер итогового .exe? Использую компилятор mingw32 версии 3.4.4. Обычная почти пустая программа с одним cout'ом занимает в итоге 450 с лишним килобайт. Эмпирическим путем удалось установить, что такой размер из-за включения <iostream>, заменив который на <cstdio>, например, программа получилась уже 15 кб.

Как бы это преодолеть? Не хотелось бы отказываться от ввода/вывода в стиле С++, но файл хочется поменьше.


Во- первых, убедись, что собираешь в релизе. Во- вторых - посмотри настройки компилятора, оптимизация по минимизации размера исполняемого кода, точное название засисит от IDE.
P.S. - Имхо, не стоит отказываться от использования проверенных и удобных библиотек, ради выигрыша в размере кода (если нет для этого каких то особо веских оснований).

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог