Войти

Показать полную графическую версию : [решено] Помогите, плиз, вынести классы в отдельные файлы.


Oleg_SK
05-06-2010, 13:52
Сабж. Сейчас программа выглядит так:


//virtual.h

class One
{
public:
One(){};
virtual ~One();
virtual void TellMe()=0;
protected:

private:

};

class Two: public One
{
public:
~Two();
virtual void TellMe();
protected:

private:

};

class Three: public One
{
public:
~Three();

protected:
virtual void TellMe();

private:

};



//virtual.cpp

#include "stdafx.h"
#include <iostream>
#include "virtual.h"

using namespace std;

One::~One()
{
cout << "!!!" << endl;
}

Two::~Two()
{
cout << "Two::destructor" << endl;
}

void Two::TellMe()
{
cout << "Two::TellMe" << endl;
}

Three::~Three()
{
cout << "Three::destructor" << endl;
}

void Three::TellMe()
{
cout << "Three::TellMe" << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
const int size=10;
One* arrey[size];
for(int i=0; i<size; i+=2)
{
arrey[i]=new Two;
arrey[i+1]=new Three;
}

Three* temp;
for(int i=0; i<size; ++i)
{

//temp = dynamic_cast<Three*>(arrey[i]);
//if(temp!=NULL)
//{
// cout << "Three object...\n";
// temp->TellMe();
//}

arrey[i]->TellMe();
}

cout << endl;

for(int i=0; i<size; ++i)
{
delete arrey[i];
}

cout << endl;

int y;
cin >> y;
return 0;
}


Хочу выделить классы в отдельные файлы, но что-то не получается (лезут непонятные ошибки)... Делаю так:


//One.h

class One
{
public:
One(){};
virtual ~One();
virtual void TellMe()=0;
protected:

private:

};



//One.cpp

#include <iostream>
#include "One.h"

using namespace std;

One::~One()
{
cout << "!!!" << endl;
}



//Two.h

#include "One.h"

class Two: public One
{
public:
~Two();
virtual void TellMe();
protected:

private:

};



//Two.cpp

#include <iostream>
#include "Two.h"

using namespace std;

Two::~Two()
{
cout << "Two::destructor" << endl;
}

void Two::TellMe()
{
cout << "Two::TellMe" << endl;
}



//Three.h

#include "One.h"

class Three: public One
{
public:
~Three();
virtual void TellMe();

protected:

private:

};



//Three.cpp

#include <iostream>
#include "Three.h"

using namespace std;

Three::~Three()
{
cout << "Three::destructor" << endl;
}

void Three::TellMe()
{
cout << "Three::TellMe" << endl;
}



//virtual.cpp

#include "stdafx.h"
#include <iostream>
#include "One.h"
#include "Two.h"
#include "Three.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
const int size=10;
One* arrey[size];
for(int i=0; i<size; i+=2)
{
arrey[i]=new Two;
arrey[i+1]=new Three;
}

//Three* temp;
for(int i=0; i<size; ++i)
{
//(dynamic_cast<Three*>(arrey[i]))->TellMe();

//temp = dynamic_cast<Three*>(arrey[i]);
//if(temp!=NULL)
//{
// cout << "Three object...\n";
// temp->TellMe();
//}
arrey[i]->TellMe();
}

//Three test;
//test.TellMe();

cout << endl;

for(int i=0; i<size; ++i)
{
delete arrey[i];
}

cout << endl;

int y;
cin >> y;
return 0;
}

Хотелось бы узнать: что я делаю не так?

P.S: Использую Visual Studio 2010.

Oleg_SK
05-06-2010, 17:26
Проблема решена. Для этого потребовалось сделать следующее:
1) В файлах Two.h и Three.h заменил инклюд файла One.h на объявление: class One;
2) Учел особенности работы Visual Studio; проинклюдил все свои заголовочные файлы и файл iostream в файле stdafx.h, а из своих cpp-файлов эти инклюды убрал, заменив на инклюд stdafx.h.

pva
05-06-2010, 17:38
ещё бы хотелось узнать какие именно ошибки лезут. Если о том, что классы уже определены, то:
сборка программы на с/с++ состоит из 3х этапов:
1. препроцессинг,
2. комлиляция
3. связывание (linking).
На певом этапе:
1. весь текст собираемого модуля сливается в один файл (#include) в одну строчку
2. выполняются директивы препроцессора по замене текста #define
3. удаляются комментарии
4. раскрываются так называемые триграфы
5. соединяются строчные константы, разделённые пробелами "sd\nfds" "123" -> "sd<код символа \n>fds123"

допустим есть 3 файла:

1.h:
int a;

2.h:
#include "1.h"
int b;

3.cpp:
#include "1.h"
#include "2.h"

после препроцессинга 3.cpp вместо #include будет содержимое указанных файлов, т.е.

int a;
int a;
int b;

такой код не проглотится компилятором, потому что переопределяется переменная a. Чтобы не было таких подвохов, используют хитрость:

1.h:
#ifndef 1_H
#define 1_H
int a;
#endif

теперь после первого включения 1.h препроцессор запомнит значение 1_H и (следуя инструкции #ifndef) будет в следующий раз пропускать содержимое этого файла.
Сделай то же самое, и у тебя заработает

Oleg_SK
05-06-2010, 18:11
pva
#ifndef 1_H
#define 1_H
int a;
#endif
Благодарю за информацию. На данный момент, я проинклюдил все свои заголовочные файлы в файле stdafx.h, в котором первой же инструкцией идет #pragma once, которая AFAIK служит для того-же, что и эта конструкция- исключает повторный инклюд файла.

Drongo
05-06-2010, 18:15
pva, Красиво объяснил. :up: Я так писал всегда, просто потому что в книге написано было именно так и без пояснений почему так. :)1.h:
#ifndef 1_H
#define 1_H
int a;
#endif »




© OSzone.net 2001-2012