[C++] Makro für Klassendefinition

Jellysheep

Erfahrenes Mitglied
Hi,
kann man ein Makro definieren, was den Code von a nach b ändert?
C++:
//a
jclass Abc{
    void f(){}
};

//b
class Abc:public Bcd{
    const char* toString(){
        return "Abc";
    }
    void f(){}
};
Ist das möglich oder kann man das so ähnlich durchführen?
 
Zuletzt bearbeitet:
Wo willst du ein Makro dafür definieren und wofür? Solltest du Eclipse verwenden, dann kannst du in den Einstellungen unter C/C++ -> Codestyle deine eigenen Templates zusammenbauen bzw. anpassen, aber das lohnt sich in der Form eigentlich nur, wenn du sie ständig einsetzt, sonst wird das nur in einem ständigen Ändern/Löschen enden.
 
Das Makro möchte ich verwenden, um Klassen definieren zu können, die wie in Java einen Klassennamen enthalten. Diesen möchte ich nicht bei jeder Klasse definieren, sondern gleich abhängig vom Namen der Klasse machen.
Eclipse verwende ich nicht, sondern Visual C++.
Ich habe schon das versucht, aber das funktioniert leider nicht:
C++:
//1. Versuch
#define jclass x{y} class x:Bcd{const char* classname(){return #x;}y};
//2. Versuch
#define jclass(x,y) class x:Bcd{const char* classname(){return #x;}y};
 
Hallo Jellysheep,

ich würde das eher etwas anders lösen. Auf deine Art hat die jclass keine Möglichkeit, diese Standardimplementierung von toString zu überschreiben. Probier es mal so:

C++:
include <iostream>

#define jclass_begin(klass)\
  class klass : public Bcd {\
    protected:\
      virtual const char* getClassName() {\
        return #klass;\
      }\
    private:

#define jclass_end };


class Bcd {
 public:
  virtual const char* toString() {
    return getClassName();
  }

 protected:
  virtual const char* getClassName() {
    return "Bcd";
  }
};

jclass_begin(Def)
  void f(){}
jclass_end

jclass_begin(Ghi)
 public:
  const char* toString() {
    return "Lorem ipsum";
  }
jclass_end

int main(int argc, char* argv[]) {
  Def def;  
  std::cout << def.toString() << std::endl; // => Def
  Ghi ghi;
  std::cout << ghi.toString() << std::endl; // => Lorem ipsum
}

Grüße,
Matthias
 
Vielen Dank, Matthias, das funktioniert perfekt! :)
Ich hab das Makro noch ein bisschen abgeändert, sodass man ")" statt jclass_end am Ende hat, hier mein Endergebnis:
C++:
class Object{
public:
	virtual string getClassName(){
		return string("Object");
	}
	virtual const char* toString(){
		return (getClassName()+"_Instance").c_str();
	}
}

#define jclass(classname,members)\
	class classname : public Object {\
	public:\
		virtual string getClassName() {\
			return string(#classname);\
		}\
	private:\
		members\
	};

#define jclass2(classname,superclass,members)\
	class classname : public Object, superclass {\
	public:\
		virtual string getClassName() {\
			return string(#classname);\
		}\
	private:\
		members\
	};

jclass(Abc,
public:
	const char* f(){
		return "f";
	}
)

jclass2(String, public string,
public:
	String():string(""){}
)

int main(int argc, char* argv[])
{
	Abc abc;
	cout<<abc.f()<<endl<<abc.getClassName()<<endl;
}
Die Makros sind wirklich eine tolle Sache! :-)
 
Zuletzt bearbeitet:
Vielen Dank, Matthias, das funktioniert perfekt! :)
Ich hab das Makro noch ein bisschen abgeändert, sodass man ")" statt jclass_end am Ende hat, hier mein Endergebnis:
Das funktioniert so nicht. Schreib mal ein Komma in eines der Member, dann siehst du auch warum.

C++:
class Object{
public:
	virtual string getClassName(){
		return string("Object");
	}
	virtual const char* toString(){
		return (getClassName()+"_Instance").c_str();
	}
}
Diese Definition von toString endet bestenfalls in einem Absturz. Du gibst hier einen Zeiger auf einen Speicherbereich zurück, der beim Verlassen der Methode freigegeben wird.

Grüße,
Matthias
 
Das funktioniert so nicht. Schreib mal ein Komma in eines der Member, dann siehst du auch warum.
Du hast Recht, das ist mir nicht aufgefallen. Ok, dann ändere ich es wieder. :D

Diese Definition von toString endet bestenfalls in einem Absturz. Du gibst hier einen Zeiger auf einen Speicherbereich zurück, der beim Verlassen der Methode freigegeben wird.
Achso. Deshalb kommen so seltsame Zeichen heraus. (!) :-)

Nochmal eine (vorläufige) Endversion:

C++:
template <class T>
inline std::string to_string (const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}

class Object{
public:
	virtual string getClassName(){
		return string("Object");
	}
	Object(){}
	virtual string toString(){
		return (getClassName().append("_Instance"));
	}
	void print(){
		Console<<toString();
	}
	void println(){
		Console<<toString();
	}
};

#define jclass(classname)\
	class classname : public Object {\
	public:\
		virtual string getClassName() {\
			return string(#classname);\
		}\
	private:

#define jclass2(classname,superclass)\
	class classname : public Object, superclass {\
	public:\
		virtual string getClassName() {\
			return string(#classname);\
		}\
	private:

#define jend };

jclass(Abc)
public:
	const char* f(){
		return "f";
	}
jend

jclass2(String, public string) 
public:
	String():string(""){}
	virtual string toString(){
		return string(*this);
	}
jend

std::ostream& operator<<(std::ostream& o, Object& s){
	return o<<s.toString();
}

jclass(Integer)
	int i;
public:
	Integer(int x):i(x){}; //2
	Integer():i(-1){}
	virtual string toString(){
		return to_string<int>(i);
	}
jend

void print(Object& o){
	o.print();
}
void print(int i){
	Integer(i).print();
}
void println(Object& o){
	o.println();
}
void println(int i){
	Integer(i).println();
}


int main(int argc, char* argv[])
{
	Abc abc;
	cout<<abc.f()<<endl<<abc<<endl;
	println(4);
	Integer i;
	i = 4;
	cout<<i<<endl;
	Object o = i;
	o.print();
	int j = i;
        println(j);
}
 
Zuletzt bearbeitet:
Zurück