#define CLASS_NAME CLASS
CLASS_NAME* pclass - new CLASS_NAME
строка -> код
наверное, странный вопрос.
есть ли возможность заставить компилятор
интерпретировать строку, типа
char* szcode = "CLASS* pclass = new CLASS;",
встречающуюся по ходу программы, как код.
"заставить компилятор интерпретировать" нельзя.
в макроопределениях есть возможность конвертировать после раскрытия параметр в строку. я об операторе #
(типа #define macro(data) #data ----> "data").
вопрос.
есть ли возможность сделать обратное.
например:
#define macro(data) new ???data
где-то в программе:
{
char* szdata = "CLASS";
CLASS* pclass = macro(szdata) //----> CLASS* pclass = new CLASS;
}
#define macro(data) #data ----> "data"
Во втором же примере ты хочешь чуда: чтобы компилятор (я правильно понял, компилятор? т.е. на compiled-time) раскрывал значение переменной:
macro(szdata) ----> CLASS* pclass = new CLASS;
Так не бывает. Кроме того не вижу в этом смысла. Можешь сделать через макрос:
Код:
Но зачем? Если ты определяешь класс во время компиляции, то чего бы его не определять явно.
Если ты хочешь, чтобы создавался объект определенного класса во время выполнения программы, то причем тут компилятор? Здесь в общем случае нужна фабрика с набором if-ов, но будут создаваться объекты только определенных классов да и то, по-хорошему, с общим интерфейсом:
Код:
class IClass {};
class Class1 :public IClass {};
class Class2 :public IClass {};
class Class3 :public IClass {};
IClass* CreateObject(string& className)
{
IClass pClass = 0;
if(strdata == "Class1") pClass = new Class1;
else if(strdata == "Class2") pClass = new Class2;
else if(strdata == "Class3") pClass = new Class3;
return pClass;
}
class Class1 :public IClass {};
class Class2 :public IClass {};
class Class3 :public IClass {};
IClass* CreateObject(string& className)
{
IClass pClass = 0;
if(strdata == "Class1") pClass = new Class1;
else if(strdata == "Class2") pClass = new Class2;
else if(strdata == "Class3") pClass = new Class3;
return pClass;
}
Набор if-ов можно заменить ассоциативным массивом или switch-ом c хешом от строки, можно ввести авторегистрацию классов, но суть останется той же.
#define macro(data) new ???data
где-то в программе:
{
char* szdata = "CLASS";
/*здесь он проверяет переменную szdata и убирает первую и вторую кавычки: подставляется только текст*/
CLASS* pclass = macro(szdata) //----> CLASS* pclass = new CLASS;
}
--почему я не определяю класс явно.
потому, что не известно, какие классы и сколько (все они наследуют от одного предка). конечно, можно использовать if'ы и т. п. просто возник вопрос, есть ли средства у проепроцессора.
Что конкретно тебе надо получить? Не на уровне создания объекта а выше.
Что значит "не известно, какие классы и сколько"?
char* szdata = "CLASS"; <- здесь же ты пишешь известное имя
откуда взяться неизвестным?
Что значит "проверяет переменную szdata" ?
Ты видишь разницу между записью
CLASS* pclass = macro(szdata)
и
CLASS* pclass = macro("CLASS")
О! Хочешь решение?
Код:
#define macro(name) new name;
#define szdata CLASS
CLASS* pclass = macro(szdata)
#define szdata CLASS
CLASS* pclass = macro(szdata)
Так ты наверняка запутаешь вероятного противника :D
если хотите, вот конкретика.
классов, допустим, 3.
CLASS_ {...};
CLASS_1 : public CLASS_ {...};
CLASS_2 : public CLASS_ {...};
CLASS_3 : public CLASS_ {...};
class MOM
{public:
CLASS_** m_pObjMas;//массив указателей на производные от CLASS_
...
};
возник вопрос: есть ли способ без if' ов в конструкторе MOM заполнить
MOM::m_pClassMas произвольным числом указателей на произвольные объекты, производные от CLASS_.
в частности, можно ли это сделать на этапе препроцессирования.
--что касается проверки фактического аргумента макорса при его раскрытии. почему вы не считаете возможным существование процесса, противоположного применению оператора # в макросе.
если может действовать оператор #, то и "мой гипотетический" :) оператор "снятия кавычек" также имеет право на существование. компилятору этот процесс не должен доставить особого труда.
[/QUOTE]
Так не бывает! Это не магия, а программирование.
[QUOTE=smax13]
возник вопрос: есть ли способ без if' ов в конструкторе MOM заполнить
MOM::m_pClassMas произвольным числом указателей на произвольные объекты, производные от CLASS_.
в частности, можно ли это сделать на этапе препроцессирования.
[/QUOTE]
На этапе предпроцессинга, компиляции и линковки НИКАКИЕ инициализации не осуществляются! Ничего заполнить на перечисленных этапах нельзя. Может ли трактор на этапе сборки на конвеере пахать землю?
[QUOTE=smax13]--что касается проверки фактического аргумента макорса при его раскрытии. почему вы не считаете возможным существование процесса, противоположного применению оператора # в макросе.
если может действовать оператор #, то и "мой гипотетический" :) оператор "снятия кавычек" также имеет право на существование. компилятору этот процесс не должен доставить особого труда.[/QUOTE]
macro(szdata)
что-то я здесь не вижу кавычек... какие кавычки надо убрать?
[/QUOTE]
[QUOTE=smax13]
char* szdata = "CLASS";
/*здесь он проверяет переменную szdata и убирает первую и вторую кавычки: подставляется только текст*/
CLASS* pclass = macro(szdata) //----> CLASS* pclass = new CLASS;
[/QUOTE]
--почему я не определяю класс явно.
потому, что не известно, какие классы и сколько (все они наследуют от одного предка). конечно, можно использовать if'ы и т. п. просто возник вопрос, есть ли средства у проепроцессора.[/QUOTE]
Как компилятор уберет кавычки, если это переменная-строка и она может поменяться во время выполнения программы, т. е. во время компиляции ее содержимое неизвестно? Даже если каким-то чудом были бы для этого средства, это были бы ну никак не средства препроцессора.
Вот например:
Код:
char *szdata = "CLASS";
some_function (szdata);
CLASS *pclass = macro (szdata); // Как компилятор может узнать
// содержимое строки szdata в данной точке, ведь функция
// some_function могла изменить ее содержимое.
some_function (szdata);
CLASS *pclass = macro (szdata); // Как компилятор может узнать
// содержимое строки szdata в данной точке, ведь функция
// some_function могла изменить ее содержимое.
Скажу больше: информация обо всех именах (переменных, типов...) после компиляции теряется (за некоторыми исключениями).
Такое возможно только в интерпретируемых языках, и во многих из них это реализовано.
Если ты под szdata имел в виду строку-константу, которая точно не изменится, используй (как сказал Green) макроопределения:
#define CLASSNAME CLASS
...
CLASS *pclass = new CLASSNAME;
или
#define CREATEOBJECT(var) CLASS *var = new CLASS
...
int main ()
{
CREATEOBJECT (pclass);
// Это заменится на CLASS *pclass = new CLASS;
};
--в программровании бывает, вспомните хотя бы SomeFunc(...);
--что-то нас всё не в ту сторону клонит.
я не собираюсь использовать имя переменной в качестве фактического
агрумента макроса. понятно, что это не пройдёт.
я хочу посмотретль на компилятор как, в первую очередь, на
лексический интерпретатор.
гипотетически.
#define macro(data) new <some operator>data;
char* sztype_name = "CLASS";
CLASS* pclass = macro(sztype_name);
-он раскрывает макрос и видит <some operator>,
CLASS* pclass = new <some operator>sztype_name;
-ищет в тексте имя фактического аргумента макроса (sztype_name);
-определяет (или уже знает, т. к. используется <some operator>), что это строка,
-(дописывет в текст то, что в кавычках строки) или делает, что-то другое -- не знаю.
ВОПРОС. существует ли подобный <some operator>.
я ничего не слышал - вот и спрашиваю.
to Cheburator
компилируйте debug-версию. если на MVCPP вся отладочная информация в .pdb.
ВОПРОС. существует ли подобный <some operator>.
я ничего не слышал - вот и спрашиваю.
[/QUOTE]
Нет не существует, но можно сделать, см. мой пример с CreateObject.
[QUOTE=smax13]
to Cheburator
компилируйте debug-версию. если на MVCPP вся отладочная информация в .pdb.[/QUOTE]
Ну на то она и ОТАДОЧНАЯ информация, что используется только отладчиком.
жаль, что нет.
спасибо.
Код:
#define macro new CLASS;
CLASS* pclass = macro;
CLASS* pclass = macro;
При смене класса менять придется только строку #define macro (при условии что класс производный от CLASS).
Ну если уж тебе нужен полный лексический (и даже синтаксический) анализатор, попробуй так:
Код:
CLASS *pclass =
#include "myfile.h"
;
#include "myfile.h"
;
А в файле myfile.h пиши что душе угодно.
Ну если уж тебе нужен полный лексический (и даже синтаксический) анализатор, попробуй так:
Код:
CLASS *pclass =
#include "myfile.h"
;
#include "myfile.h"
;
А в файле myfile.h пиши что душе угодно.[/QUOTE]
И этот человек говорил о "хорошем и выработанном годами принципе модульного программирования" ? :D
Я бы за такое не бил бы по рукам, а отрезал их вовсе... как рудимент.
P.S. Без обид, это была шутка (см. смайлик), но подобный стиль программирования, действительно, не очень хороший.
Ну, лично я с крыши небоскреба прыгать не собираюсь, но если кому-то это сильно надо - я проинструктирую его как это можно сделать :)