Часовой пояс: UTC + 3 часа




Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 1730 • Страница 19 из 87<  1 ... 16  17  18  19  20  21  22 ... 87  >
  Пред. тема | След. тема 
В случае проблем с отображением форума, отключите блокировщик рекламы
Автор Сообщение
 

Member
Статус: Не в сети
Регистрация: 24.07.2005
Откуда: Moscow
Спецы, подскажите, в инете искал - не нашел:

Есть функция, в нее передается массив. Для корректной работы функции ей необходимо знать кол-во элементов передаваемого массива. sizeof() внутри функции не работает, а больше я не знаю способов определить кол-во элементов.

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



Партнер
 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
Не реально с обычными С массивами, только передавать длину, да и универсальность от этого не теряется. Вариант 2 - использовать std::vector.

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 24.07.2005
Откуда: Moscow
А где можно почитать про 2-й вариант? Я совсем недавно начал на СИ программировать, многое не понятно..


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
Алканаффт если в С, то пролет, это вариант для С++.

_________________
Ку ку


 

Алканаффт прочитать можно в MSDN


 

Member
Статус: Не в сети
Регистрация: 31.08.2005
Откуда: Мир
Помогите, пожалуйста, подключиться к Базе данных на С/С++
Я написал вот такой код:
Код:
#include <stdio.h>
#include "mysql.h"
#define def__host__name "localhost"
#define def_user_name "db_new"
#define def_password "prolmoy)"
#define def_db_name "db_new" 
MYSQL  *conn;                         
int
main (int argc, char *argv[j)
{
conn = mysql_init (NULL);
mysql_real_connect (
conn,                   
def_host name,
def_user_name,
def_password,
def_db_name,
0,
NULL,
0);
mysql_close(conn);
exit(0);}

Вобщем взял этот пример из книжки..но компилятор зацикливается и прекращает компилирование, выдав 103 ошибки, к=е жутко ругают файл mysql_com.h
Я его взял из комплекта поставки MySQL, так что не думаю что с ним чтото нето. Помогите, плиз, разобраться!

_________________
Loading...


 

Member
Статус: Не в сети
Регистрация: 14.03.2004
Откуда: Москва
брррррр... список ошибок дай

_________________
ФИЗТЕХ- рулез, ФАКИ - сила, Кванты тоже хорошо


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Прошу помощи! Пишу программу, не знаю как лучше организовать данные с позиций ООП. Программа будет отображать графически(3Д и 2Д) и работать с разными типами данных. Один объект в программе может быть поверхностью, другой - набором точек в трехмерном пространстве, третий набором линий. Объектов может быть любое количество. Соответственно мне надо определять классы TSurface, TPoints, TLines, для них реализовать все необходимые методы, в частности метод отображения на экране. Но, поскольку объектов каждого типа может быть произвольное число, мне надо определять 3 контейнера? По одному для каждого типа и, например для отображения всех объектов на экране должен быть такой код:

Код:
vector <TSurface> v_Surface;
vector <TPoints> v_Points;
vector <TLines> v_Lines;
....
for (int i=0; i<v_Surface.size(); i++)       //Отображение поверхностей
 v_Surface[i].Draw;
for (int i=0; i<v_Lines.size(); i++)          //Отображение наборов линий
 v_Lines[i].Draw;
for (int i=0; i<v_Points.size(); i++)         //Отображение наборов точек
 v_Points[i].Draw;

И так для каждого типа. По-моему не очень рациональная реализация, ведь надо повторять код для каждого типа.. Как это можно сделать лучше?


 

Member
Статус: Не в сети
Регистрация: 24.12.2005
kexman
Для этого есть виртуальные функции. Создаёшь базовый класс с интерфейсом и наследуешь от него свои сюрфейсы и пойнты. А в векторе хранишь указатели на базовый класс, реально указывающие на твои объекты. Например:
Код:
class Drawable // abstract
{
public:
    virtual void Draw() = 0;
};

class Point : public Drawable
{
public:
    virtual void Draw() { /* реализация отображения точки */ }
    // ...
private:
    int x, y;
    // ...
};

class Surface : public Drawable
{
public:
    virtual void Draw() { /* реализация отображения поверхности */ }
    // ...
private:
    // ...
};

....

vector<Drawable*> allMyObjects;  // лучше завернуть в класс-обёртку, чтобы не забыть удалить объекты при уничтожении вектора

....

for ( int i = 0; i < allMyObjects.size(); ++i )
    allMyObjects[i]->Draw();


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Спасибо огромное! Вначале не понял, потом почитал Либерти, разобрался.
Единственное, непонятно про лучше завернуть в класс-обёртку, чтобы не забыть удалить объекты при уничтожении . Это что такое?
Добавлено спустя 3 минуты, 31 секунду
Блин, а я и не знал, оказывается ООП и в частности С++ дает такие охренительные возможности, жуть! дух захватывает, наследование - супер!


 

Member
Статус: Не в сети
Регистрация: 24.12.2005
kexman писал(а):
Единственное, непонятно про лучше завернуть в класс-обёртку, чтобы не забыть удалить объекты при уничтожении . Это что такое?

Ну, дело в том, что при уничтожении вектора, память выделенная под объекты, не освободится, т.к. нужно вручную заделетить каждый указатель. Т.е.:
Код:
vector<Drawable*> objs;
...
// создаём объекты
objs.push_back( new Surface );
...
// освобождаем память
for ( int i = 0; i < objs.size(); ++i )
    delete objs[i];
Если этого не сделать, произойдёт утечка памяти (и возможно других ресурсов, если ты их выделяешь в конструкторе своих объектов). Поэтому лучше сделать небольшой класс-обёртку для вектора, который в деструкторе удалит всё автоматически:
Код:
class VectorDrawsPtr
{
public:
    VectorDrawsPtr() {}
    ~VectorDrawsPtr() { for ( int i = 0; i < vec_.size(); ++i ) delete vec_[i]; }

    // перегружаешь необходимые операторы, вводишь необходимые функции...
    Drawable* operator[] ( size_t i ) const { return vec_[i]; }
    size_t size() const { return vec_.size(); }
    // ...
private:
    vector<Drawable*> vec_;
};

Добавлено спустя 3 минуты
Кстати, чуть не забыл :), в базовом классе обязательно нужен виртуальный деструктор:
Код:
class Drawable // abstract
{
public:
    virtual ~Drawable() = 0;
    virtual void Draw() = 0;
};


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
Билли Бонс писал(а):
for ( int i = 0; i < vec_.size(); ++i ) delete vec_[i];
Интересно написал, использовал префиксный инкремент, но он тут бесполезен, ибо используются не итераторы а простой индекс :D

Добавлено спустя 4 минуты, 47 секунд
ИМХО лучше нечто такого (правда пока незнаю соберется это или нет :)))
Код:
template <class T> class VectorWrapper : public std::vector<T>
{
public:
   ~VectorWrapper()
   {
       for(typename std::vector<T>::iterator i = begin(); i != end(); ++i)
         delete *i;
   }
}

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 24.12.2005
Daemon писал(а):
Интересно написал, использовал префиксный инкремент, но он тут бесполезен, ибо используются не итераторы а простой индекс :D
Привычка, однако. :) И так красивее.

Daemon писал(а):
ИМХО лучше нечто такого ...
Может и лучше, сейчас лень сравнивать. :)


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Билли Бонс
Но твой класс же не будет содержать в себе все методы контейнера vector. Лучше наверное как-нибудь наследовать от класса вектор, чтобы не перегружать потом push_back(), size()... Вроде вариант Daemon как раз под это подходит, только я не знаю еще, как использовать шаблоны.


 

Member
Статус: Не в сети
Регистрация: 24.12.2005
kexman Обычно всё равно для своей коллекции требуются свои методы, а не вектора (векторные бывают иногда даже нежелательны). Концепции проектирования, пожалуй, в двух словах не расскажешь, это приходит с опытом (при желании изучать их, конечно). Ни разу не встречал на самом деле наследование от стандартных контейнеров. :)

kexman писал(а):
только я не знаю еще, как использовать шаблоны
Ну, класс VectorWrapper можешь использовать также как vector, разве что для пущей безопасности сделать так:
Код:
template <class T> class VectorWrapper : public std::vector<T>
{
};

template <class T*> class VectorWrapper : public std::vector<T*>
{
public:
   ~VectorWrapper()
   {
       for(typename std::vector<T>::iterator i = begin(); i != end(); ++i)
         delete *i;
   }
};


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Билли Бонс
Твой код почему-то приводит к ошибке:

error C2917: 'T *' : invalid template-parameter
error C3855: 'VectorWrapper': template parameter 'T' is incompatible with the declaration
Добавлено спустя 2 минуты, 53 секунды
Билли Бонс писал(а):
Ни разу не встречал на самом деле наследование от стандартных контейнеров.

Но эта конструкция
Код:
template <class T> class VectorWrapper : public std::vector<T>
не наследование от класса vector?


 

Member
Статус: Не в сети
Регистрация: 24.12.2005
kexman писал(а):
Твой код почему-то приводит к ошибке:
Сорри, давненько шаблоны не писал. :oops: Во:
Код:
template <class T> class VectorWrapper : public std::vector<T>
{
};

template <class T> class VectorWrapper<T*> : public std::vector<T*>
{
public:
   ~VectorWrapper()
   {
       for (typename std::vector<T*>::iterator i = this->begin(); i != this->end(); ++i)
         delete *i;
   }
};

kexman писал(а):
Но эта конструкция ... не наследование от класса vector?
Почему не наследование? Наследование... Я о том, что на практике не встречал. :)


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
Ага, частичная специализация с глюком ;) Поправде говоря я особо тоже не натыкаюсь на либы, там где часто испольщуются шаблоны. Кроме STL конечно, а так это МС со своими WTL, ATL любит лепить их куда не попадя :)
Билли Бонс писал(а):
Ни разу не встречал на самом деле наследование от стандартных контейнеров.
Ага, я тоже, потому что функторы руллят, выше описаное действие лучше через for_each сделать :)

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Есть 2 вопроса:
1) объявляю класс в теле какой-нибудь функции:
Код:
void myfunc()
{
  CMyClass m_object;
  ....
  // Действия
  //
}

Если у меня для класса CMyClass есть деструктор, будет ли он выполнятся по окончании функции myfunc() или мне надо его вызывать явно, что-то типа
Код:
delete m_object;

?
2) Если у меня объявлен динамический массив
Код:
 float **grid;
 grid=new float*[numX];
 for (int i=0; i<numX; i++)
     grid[i]=new float[numY];

то правильное удаление его выглядит так:
Код:
 for (int i=0; i<numX; i++)
     delete grid[i];
 delete grid;

?


 

Member
Статус: Не в сети
Регистрация: 24.12.2005
1.
kexman писал(а):
Если у меня для класса CMyClass есть деструктор, будет ли он выполнятся по окончании функции myfunc()
Да.

2. Правило: new - delete, new[] - delete[]
Код:
for ( int i = 0; i < numX; ++i )
    delete[] grid[i];
delete[] grid;

Но так лучше не делать. Юзай вектор или, на крайняк, так:
Код:
float (*grid)[MAX_X];
grid = new float[MAX_Y][MAX_X];
grid[2][5] = 1.0f;
delete[] grid;


Показать сообщения за:  Поле сортировки  
Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 1730 • Страница 19 из 87<  1 ... 16  17  18  19  20  21  22 ... 87  >
-

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB | Kolobok smiles © Aiwan