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

Ваш аккаунт

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

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

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

Помогите ламеру с классами

4.1K
27 сентября 2006 года
Zeran
80 / / 21.07.2006
Вобщем нужно вот класс написать свой.Пишу так:
 
Код:
class Project
{
public:
        void SetCreated(void) { Created = 1; }
private:
        int Created;
};

подскажите плиз как в проге потом вызвать данную ф-цию?Пробовал
Project *a;
a.SetCreated();
и
a->SetCreated();

оба варианта неверны...
Подскажите пожалуйста что я не правильно делаю и как правильно?
Заранее спасибо!
240
27 сентября 2006 года
aks
2.5K / / 14.07.2006
Первый вариант не верен потому, что объявлен указатель на объект, а не сам объект. К указателем доступ через -> ,а не точку.
Второй не верен, видимо потому что это указатель. А раз указатель, прежде чем обращаться к обеъекту - надо его сначала создать и передать его адресс в указатель.
Тоесть или так:
 
Код:
Project a;
a.SetCreated();


или так:
 
Код:
Project *a = new Project();
a->SetCreated();


или так:
 
Код:
Project b;
Project *a = &b;
a->SetCreated();

=))
4.1K
27 сентября 2006 года
Zeran
80 / / 21.07.2006
Не работает :(
Пишет Multiple declaration for 'a'
А если набирать, то после "->" пишет
[COLOR="DarkRed"][C++ Error] Unit1.cpp(1): Unable to invoke Code Completion due to errors in source code[/COLOR]
Если можно напиши плиз простенький примерчик класса и выхова его ф-ций для Б6...
1.9K
27 сентября 2006 года
SABROG
242 / / 26.01.2006
Возьми за правило описание класса делать в заголовках (.h/.hpp), а реализацию в исходном файле (.c/.cpp).

//Class.h
Код:
class TClass
{
private:
int iVar; // переменная доступная только из методов класса
void fFunc(); // метод доступный только из других методов класса
public:
int iVar2; // переменная доступная везде
  TClass(); // конструктор
  void pubFunc(int); // метод доступный для вызова отовсюду
  ~TClass(); // деструктор
};


//Class.cpp
Код:
#include "Class.h"
//-------------------------------------------------------------------------
TClass::TClass() // конструктор. Вызывается автоматически при создании экземпляра объекта класса. Можно использовать для инициализации переменных. Как и в функцию можно добавить параметры.
{
}
//-------------------------------------------------------------------------
TClass::~TClass() // деструктор. Вызывается автоматически при уничтожении экземпляра объекта класса. Тут можно освободить области памяти, которые не освобождаются автоматичеси, выгрузить какие-то данные.
{
}
//-------------------------------------------------------------------------
int TClass::fFunc()
{
return iVar2 * 2;
}
//-------------------------------------------------------------------------
int TClass::pubFunc(int i)
{
iVar2 = i;
return fFunc();
}

//Unit1.cpp
 
Код:
TClass a; // создаем один экземпляр объекта класса
a.pubFunc(1); // вызываем публичный метод
4.1K
27 сентября 2006 года
Zeran
80 / / 21.07.2006
Уже все работает, протупил просто :)
Еще вот такой вопросик, я хочу в классе использовать переменную типа TADOConnection, подскажите плиз как ее обьявить и как инициализировать?
1.9K
27 сентября 2006 года
SABROG
242 / / 26.01.2006
TADOConnection не переменная, это класс ! :)
Тебе надо завести приватный указатель на экземпляр объекта класса TADOConnection. Создавать экземпляр объекта можно либо в конструкторе твоего класса либо в публичном методе, написать, что-то типа метода Initialize();. В деструкторе можно прописать удаление экземпляра объекта класса. Если хочешь написать просто wrapper для ADO компонентов, то можно унаследовать класс.
4.1K
27 сентября 2006 года
Zeran
80 / / 21.07.2006
[QUOTE=SABROG]TADOConnection не переменная, это класс ! :)
Тебе надо завести приватный указатель на экземпляр объекта класса TADOConnection. Создавать экземпляр объекта можно либо в конструкторе твоего класса либо в публичном методе, написать, что-то типа метода Initialize();. В деструкторе можно прописать удаление экземпляра объекта класса. Если хочешь написать просто wrapper для ADO компонентов, то можно унаследовать класс.[/QUOTE]
Ну, как бы это выразится...а можно примерчик?Ато я что-то мало чего понял... :)
З.Ы: ну просто очень очень нужно!Буду весьма признателен за простенький, доступный моему уму примерчик :)

З.З.Ы: когда пишу в привате в классе:
TADOConnection *AC1;
а в конструкторе класса:
AC1 = new TADOConnection();
пишет
[COLOR="DarkRed"][C++ Error] Classes.cpp(43): E2285 Could not find a match for 'TADOConnection::TADOConnection()'[/COLOR]
4.1K
27 сентября 2006 года
Zeran
80 / / 21.07.2006
Ну подскажите плиз!Ну очень нужно, горю!!!Киньте кто-то примерчик...:(
309
27 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
Цитата:
Ну, как бы это выразится...а можно примерчик?Ато я что-то мало чего понял...
З.Ы: ну просто очень очень нужно!Буду весьма признателен за простенький, доступный моему уму примерчик


Пожалуйста

в .h файле

Код:
// Подключаем заголовки для объявления объектов БД
#include <ADODB.hpp>
#include <DB.hpp>
// ...............

class TcDB_Interface
{
private:[INDENT]
TADOConnection *_fConnection; // Закрытое поле - указатель на объект
[/INDENT]
public:[INDENT]
__property TADOConnection *Connection = {read = _fConnection}; // Публичное свойство для обращения к объекту - указатель на объект

__fastcall TcDB_Interface (void); // Конструктор объекта
__fastcall ~TcDB_Interface (void); // Деструктор объекта
[/INDENT]};


в .cpp файле

 
Код:
__fastcall TcDB_Interface::TcDB_Interface (void)
{
     _fConnection = new TADOConnection (NULL); // Создание вложенного объекта и связывание с полем-указателем
}
__fastcall TcDB_Interface ::~TcDB_Interface (void)
{
    delete _fConnection; // Удаление вложенного объекта по его укзателю
}


Пойдёт пример.
А самое главное в C++ - это понять, что такое "указатель" и как выделять/удалять объекты из памяти с использованием этих указателей. Без понимания этого, дальше "Hello world" не продвинешься ;)
4.1K
27 сентября 2006 года
Zeran
80 / / 21.07.2006
Сделал все точто так же, вот что выдало...
Каак это поправиьт? :(
1.9K
27 сентября 2006 года
SABROG
242 / / 26.01.2006
//Unit1.h
Код:
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ADODB.hpp>
#include <DB.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TButton *btn1;
        TADOConnection *con1;
        void __fastcall btn1Click(TObject *Sender);
private:    // User declarations
public:     // User declarations
        __fastcall TForm1(TComponent* Owner);
};
class TmClass
{
private:
public:
TADOConnection *padoCon;
  TmClass();
  ~TmClass();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

//unit1.cpp
Код:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TmClass *tc=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
tc = new TmClass;
}
//---------------------------------------------------------------------------
TmClass::TmClass()
{
        try{
        padoCon = new TADOConnection(0);

        }catch(...){
        padoCon = NULL;
        }
}
TmClass::~TmClass()
{
        if (padoCon) delete padoCon;
}
void __fastcall TForm1::btn1Click(TObject *Sender)
{
tc->padoCon->ConnectionString = "FILE NAME=Server.udl";
tc->padoCon->Connected = true;
        if(tc->padoCon->Connected){
        ShowMessage("Соединились.");
        }
}
//---------------------------------------------------------------------------
4.1K
27 сентября 2006 года
Zeran
80 / / 21.07.2006
Вобщем вот к чему я пришел...
Можно ли создать ADOConnection непосредственно в самом классе?Т.е. не кидать на форму, а создать его в классе MyClass например ADOConnection1, а потом в программе сделать вот так:
MyClass *a = new MyClass();
a->ADOConnection1->ConnectionString = "bla bla bla";
a->ADOConnection1->Connected = true;
и т.д.
Если можно напишите плиз как?
309
27 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
Sabrog
Ты что тут изваял :confused: - сам чёрт ногу сломит :eek: .
Zeran же в жизни не разберётся в этом "монументализме" :(

Тем более, что есть два недочёта
1. "TADOConnection *con1" - в описании формы. Зачем, ведь мы создаём объект отдельно?. И где объявление tc?
2. Если в строке "padoCon = new TADOConnection(0);" произойдёт ошибка, то в методе TForm1::btn1Click получим мощный Access Violation :(
3. Так как тип TmClass содержит только одно поле - указатель, и не является производным от TOBject, то его объекты лучше реализовывать напрямую, без указателей. Соответственно, не будет нужды обрабатывать его в конструкторе/деструкторе, да и сама программа быстрее работать будет

 
Код:
class TForm1: public TForm
{
// .......
private:
     TmClass tc;
// .....
};


Zeran
Так что же у тебя выдаётся? Кстати, кто выдаёт: компилятор, линковщик или же сама программа в момент выполнения.
4.1K
27 сентября 2006 года
Zeran
80 / / 21.07.2006
Дебугер выдает, я ж прикрепил скрин еррора в посте на конце 1й страницы :)
Но помому (если это возможно) луче сделать как в посте №12?
1.9K
27 сентября 2006 года
SABROG
242 / / 26.01.2006
[QUOTE=el scorpio]Sabrog
Ты что тут изваял :confused: - сам чёрт ногу сломит :eek: .
Zeran же в жизни не разберётся в этом "монументализме" :(
[/QUOTE]
Наоборот должно помочь. Так видно куда суется класс и где реализуются методы.

[QUOTE=el scorpio]
Тем более, что есть два недочёта
1. "TADOConnection *con1" - в описании формы. Зачем, ведь мы создаём объект отдельно?.
[/quote]
Подумаешь указатель лишний забыл удалить :), просто не хотелось хидеры вручную прописывать для ADOConnect.

[QUOTE=el scorpio]
И где объявление tc?
[/quote]
Посмотри внимательнее, там объявление указателя tc есть перед конструктором формы.

[QUOTE=el scorpio]
2. Если в строке "padoCon = new TADOConnection(0);" произойдёт ошибка, то в методе TForm1::btn1Click получим мощный Access Violation :
[/quote]
Получим конечно. Просто в один момент мне перехотелось писать Safe код. Принцип главное понятен.

[QUOTE=el scorpio](
3. Так как тип TmClass содержит только одно поле - указатель, и не является производным от TOBject, то его объекты лучше реализовывать напрямую, без указателей. Соответственно, не будет нужды обрабатывать его в конструкторе/деструкторе, да и сама программа быстрее работать будет
[/quote]
В этом случае будет всего один объект. Мало ли, человеку захочется сделать десяток соединений.
4.1K
27 сентября 2006 года
Zeran
80 / / 21.07.2006
Все понял, я просто делал так:
MyCmass *a = new MyClass();

и оно матюгалось, но когда сделал вот так:
MyClass *a=0;

А потом в __fastcall TForm1::TForm1:
a = new MyClass;

все начало работать гуд!
Большое всем спасибо!
З.Ы: коденет рулит!С меня море виртуального пифа :)
309
27 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=SABROG]Наоборот должно помочь. Так видно куда суется класс и где реализуются методы.[/quote]
У меня проще и понятнее было :D .

Цитата:
Посмотри внимательнее, там объявление указателя tc есть перед конструктором формы.


Где, в упор не вижу....
А, нашёл - глобальный :eek: указатель на объект. Создаётся в конструкторе формы :eek:. Угадайте с трёх раз, что получиться, если где-нибудь в процессе выполнения программы создать ещё одну "форму1" :D . Правильно - утечку памяти - потеряем указатель на существующий объект. А после удаления второй формы - очередной AV при первом же обращении к объекту.

Zeran, запомни, как "Отче наш". Если какой-нибудь объект создаётся другим - то он должен быть полем своего родителя.
Глобальных указателей на объекты не плоди - только на формы. Всё остальное пусть будет полями форм, создаваться в конструкторах форм и удаляться в их же деструкторах.
Глобальными переменными не увлекайся. Если форма или другой большой объект активно используют значение - объявляй полем объекта. Если это должны использовать другие объекты - создавай свойство, позволяющее выполнять чтение/запись свойства.
Помни, грамотно спроектированная иерархия классов - половина решения задачи. Всё остальное само-собой разрешится.

Цитата:
Получим конечно. Просто в один момент мне перехотелось писать Safe код. Принцип главное понятен.


Пусть люди принципы понимают, как положено, "с чувством, с толком, с расстановкой".

1.9K
27 сентября 2006 года
SABROG
242 / / 26.01.2006
[QUOTE=el scorpio]А, нашёл - глобальный :eek: указатель на объект.[/quote]
Это все понятно. Програмирование оно на то и программирование, чтобы дать волю своему воображению. А создание второго TForm1 это всего-лишь возможное условие постановки задачи. Но я за то, чтобы заранее делать все правильно, т.к. в будущем многое может поменяться.

[QUOTE=el scorpio]
Пусть люди принципы понимают, как положено, "с чувством, с толком, с расстановкой".[/QUOTE]
Если дальше двигаться в этом же направлении, то тема перетечет в целесообразность использования new/delete, смарт поинтеры, стандарты, стиль программирования...
4.1K
28 сентября 2006 года
Zeran
80 / / 21.07.2006
Вот тут у меня возник вопросик...
Я типа создал Коннекшн в своем классе, а как теперь сделать для него обработчики событий, например АфтерКоннект и ОнДисконнект?
[COLOR="DarkRed"]Classes.cpp[/COLOR]
 
Код:
class Project
{
public:
Project();
~Project();
       TADOConnection *Connection;
        TADOCommand    *Command;
        TADODataSet    *DataSet;
private:
};

[COLOR="DarkRed"]Classes.h[/COLOR]
Код:
Project::Project()
{
    Connection = new TADOConnection(NULL);
    Command = new TADOCommand(NULL);
    DataSet = new TADODataSet(NULL);
}
Project::~Project()
{
    delete Connection;
    delete Command;
    delete DataSet;
}
1
29 сентября 2006 года
kot_
7.3K / / 20.01.2000
здесь
309
29 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
Zeran
Не объявляй поля классов как общие - для них нужно использовать private

Кстати, если требуется создать событие для своего объекта, можно использовать следующий код

Код:
class TMyClass: public TObject
{
private:
TNotifyEvent _fOnEvent; //Обработчик события

inline void Event (void)
     {if (_fOnEvent) // Проверка наличия обработчика события
          _fOnEvent (this);} // Вызов функции - обработчика события для этого объекта

public:
     void Make_Somesing (params);
     __property OnEvent = {read = _fOnEvent, write = _fOnEvent}; // Свойство чтения/записи обработчика события
}

void TMyClass::Make_Somesing (params)
{
//Метод объекта, делающий что-нибудь :)
// ......
     this->Event(); // А здесь происходит событие объекта
// ......
}

Определение типа TNotifyEvent можно посмотреть в help'е или выбрав в контекстном меню редактора кода "Find definition".
Если требуется использовать событие другого типа (например, для объекта, наследуемого не от TObject), или передать в обработчик параметры события, можно определить свой тип события.
Тип "событие" выглядит как указатель на функцию, но имеет ключевое слово __closure.
4.1K
29 сентября 2006 года
Zeran
80 / / 21.07.2006
Ничего не понял :(
Вот например мой класс:
[COLOR="DarkRed"]Classes.cpp[/COLOR]
 
Код:
class Project
{
public:
Project();
~Project();
       TADOConnection *Connection;
        TADOCommand    *Command;
        TADODataSet    *DataSet;
private:
};

[COLOR="DarkRed"]Classes.h[/COLOR]
Код:
Project::Project()
{
    Connection = new TADOConnection(NULL);
    Command = new TADOCommand(NULL);
    DataSet = new TADODataSet(NULL);
}
Project::~Project()
{
    delete Connection;
    delete Command;
    delete DataSet;
}

Как для Connection сделать обработчик AfterConnect?
309
29 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
 
Код:
TForm1::TForm1 (...) //Типа, конструктор формы :)
{
     TProject *MyObject = new TProject(); // Создаём требуемый объект
      MyObject->Connection->OnAfterConnect = this->Connection_Event;
// ConnectionEvent (TObject *Sender) - это созданный метод класса TForm1
}


И ещё перемести указатели на объекты в private.
А то если сдуру сделаешь что-нибуть типа "MyObject->Connection = Другой_Объект", и будешь репу чесать: почему программа в Access Violation со свистом :) улетает :confused:.
4.1K
29 сентября 2006 года
Zeran
80 / / 21.07.2006
И еще один, надеюсь последний, вопросик:
Создаю в классе:
TStrings *Params;
в конструкторе:
Params = new TStrings;
а оно мне при компиле пишеть:
[COLOR="DarkRed"][C++ Error] Unit1.cpp(28): E2352 Cannot create instance of abstract class 'TStrings'[/COLOR]
[COLOR="DarkRed"][C++ Error] Unit1.cpp(28): E2353 Class 'TStrings' is abstract because of '_fastcall TStrings::Get(int) = 0'[/COLOR]
:(
1
29 сентября 2006 года
kot_
7.3K / / 20.01.2000
[QUOTE=Zeran]И еще один, надеюсь последний, вопросик:
Создаю в классе:
TStrings *Params;
в конструкторе:
Params = new TStrings;
а оно мне при компиле пишеть:
[COLOR="DarkRed"][C++ Error] Unit1.cpp(28): E2352 Cannot create instance of abstract class 'TStrings'[/COLOR]
[COLOR="DarkRed"][C++ Error] Unit1.cpp(28): E2353 Class 'TStrings' is abstract because of '_fastcall TStrings::Get(int) = 0'[/COLOR]
:([/QUOTE]
От данного класса можно наследовать, но объект данного класа создать нельзя. Потому как виртуальный он.
Если необходимо - или создавай свой или используй TStringsList.
Во блин заговорился - имелось ввиду абстрактный
309
30 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
Zeran
Есть такое понятие, как виртуализация методов класса.
В двух словах - это когда в базовом классе один метод объекта хочет вызывать другой, но, сам того не подозревая, вызывает метод производного класса этого же объекта, потому что тот объявлен "виртуальным".
А бывает так, когда неизвестно, что этот метод должен делать в базовом классе - но без этого действия не обойтись. Тогда программист пишет, что реализация такого метода "равна нулю", а уже в производных классах описывает, что этот метод должен делать для конкретного объекта. Подобные методы называются "абстрактными", соответственно классы с этими методами тоже. Объекты абстрактных классов создавать нельзя, потому что они сами по себе не могут работать.
TStrings - абстрактный класс - он не имеет своего кода для выполнения чтения-записи строк. Все эти действия реализованы в классе TStringList.
Обычно используются указатели на TStringList: "TStringList *list = new TStringList();".
Если же по какой-то причине хочется использовать указатель на TStrings - пожалуйста: "TStrings *list = new TStringList();"
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог