I have a user-defined class, say, MyClass. Suppose its definition is as follows:
class MyClass
{
int a;
int *b;
Base *c;
};
where I have
class Base
{
int base_data;
public:
Base(int) { //implementation }
virtual void some_func() = 0;
}
and
class Derived1 : public Base
{
int derived_1;
public:
Derived1(int) { //implementation }
virtual void some_func() { //implementation }
}
and
class Derived2 : public Base
{
int derived_2;
public:
Derived2(int) { //implementation }
virtual void some_func() { //implementation }
}
I would like to send an object of this class to a QTcpsocket. As per this answer, I could use a QDataStream, and with the help of this, I have implemented as follows:
friend QDataStream& operator<<(QDataStream&, const MyClass&);
friend QDataStream& operator>>(QDataStream&, MyClass&);
in the class declaration, and am considering defining it as:
QDataStream& operator<<(QDataStream &stream, const MyClass &obj)
{
stream << obj.a;
stream << obj.(*b);
stream << obj.(*Base); // assume QDataStream has been overloaded for Base already
}
As I need to send the data, I am dereferencing the pointers and sending the data it points to.
Is this the correct way to do this?
If I do send it this way, I am not able to understand how I can recreate the object at the receiving end. I am considering:
QDataStream& operator<<(QDataStream &stream, MyClass &obj)
{
stream >> obj.a;
b = new int;
stream >> obj.(*b);
Base = new //what?
stream >> obj.(*Base); // assume QDataStream has been overloaded for Base already
}
For an int pointer, I can create a new int and assign the incoming value to it. But what about a pointer of type Base? I don't know if it is of type Derived1 or Derived2.
How do I handle this?
Is there any other way to send a class object, if there is no solution here?
Thank you.
Related
Without referring to a book, can anyone please provide a good explanation for CRTP with a code example?
In short, CRTP is when a class A has a base class which is a template specialization for the class A itself. E.g.
template <class T>
class X{...};
class A : public X<A> {...};
It is curiously recurring, isn't it? :)
Now, what does this give you? This actually gives the X template the ability to be a base class for its specializations.
For example, you could make a generic singleton class (simplified version) like this
template <class ActualClass>
class Singleton
{
public:
static ActualClass& GetInstance()
{
if(p == nullptr)
p = new ActualClass;
return *p;
}
protected:
static ActualClass* p;
private:
Singleton(){}
Singleton(Singleton const &);
Singleton& operator = (Singleton const &);
};
template <class T>
T* Singleton<T>::p = nullptr;
Now, in order to make an arbitrary class A a singleton you should do this
class A: public Singleton<A>
{
//Rest of functionality for class A
};
So you see? The singleton template assumes that its specialization for any type X will be inherited from singleton<X> and thus will have all its (public, protected) members accessible, including the GetInstance! There are other useful uses of CRTP. For example, if you want to count all instances that currently exist for your class, but want to encapsulate this logic in a separate template (the idea for a concrete class is quite simple - have a static variable, increment in ctors, decrement in dtors). Try to do it as an exercise!
Yet another useful example, for Boost (I am not sure how they have implemented it, but CRTP will do too).
Imagine you want to provide only operator < for your classes but automatically operator == for them!
you could do it like this:
template<class Derived>
class Equality
{
};
template <class Derived>
bool operator == (Equality<Derived> const& op1, Equality<Derived> const & op2)
{
Derived const& d1 = static_cast<Derived const&>(op1);//you assume this works
//because you know that the dynamic type will actually be your template parameter.
//wonderful, isn't it?
Derived const& d2 = static_cast<Derived const&>(op2);
return !(d1 < d2) && !(d2 < d1);//assuming derived has operator <
}
Now you can use it like this
struct Apple:public Equality<Apple>
{
int size;
};
bool operator < (Apple const & a1, Apple const& a2)
{
return a1.size < a2.size;
}
Now, you haven't provided explicitly operator == for Apple? But you have it! You can write
int main()
{
Apple a1;
Apple a2;
a1.size = 10;
a2.size = 10;
if(a1 == a2) //the compiler won't complain!
{
}
}
This could seem that you would write less if you just wrote operator == for Apple, but imagine that the Equality template would provide not only == but >, >=, <= etc. And you could use these definitions for multiple classes, reusing the code!
CRTP is a wonderful thing :) HTH
Here you can see a great example. If you use virtual method the program will know what execute in runtime. Implementing CRTP the compiler is which decide in compile time!!! This is a great performance!
template <class T>
class Writer
{
public:
Writer() { }
~Writer() { }
void write(const char* str) const
{
static_cast<const T*>(this)->writeImpl(str); //here the magic is!!!
}
};
class FileWriter : public Writer<FileWriter>
{
public:
FileWriter(FILE* aFile) { mFile = aFile; }
~FileWriter() { fclose(mFile); }
//here comes the implementation of the write method on the subclass
void writeImpl(const char* str) const
{
fprintf(mFile, "%s\n", str);
}
private:
FILE* mFile;
};
class ConsoleWriter : public Writer<ConsoleWriter>
{
public:
ConsoleWriter() { }
~ConsoleWriter() { }
void writeImpl(const char* str) const
{
printf("%s\n", str);
}
};
CRTP is a technique to implement compile-time polymorphism. Here's a very simple example. In the below example, ProcessFoo() is working with Base class interface and Base::Foo invokes the derived object's foo() method, which is what you aim to do with virtual methods.
http://coliru.stacked-crooked.com/a/2d27f1e09d567d0e
template <typename T>
struct Base {
void foo() {
(static_cast<T*>(this))->foo();
}
};
struct Derived : public Base<Derived> {
void foo() {
cout << "derived foo" << endl;
}
};
struct AnotherDerived : public Base<AnotherDerived> {
void foo() {
cout << "AnotherDerived foo" << endl;
}
};
template<typename T>
void ProcessFoo(Base<T>* b) {
b->foo();
}
int main()
{
Derived d1;
AnotherDerived d2;
ProcessFoo(&d1);
ProcessFoo(&d2);
return 0;
}
Output:
derived foo
AnotherDerived foo
This is not a direct answer, but rather an example of how CRTP can be useful.
A good concrete example of CRTP is std::enable_shared_from_this from C++11:
[util.smartptr.enab]/1
A class T can inherit from enable_shared_from_this<T> to inherit the shared_from_this member functions that obtain a shared_ptr instance pointing to *this.
That is, inheriting from std::enable_shared_from_this makes it possible to get a shared (or weak) pointer to your instance without access to it (e.g. from a member function where you only know about *this).
It's useful when you need to give a std::shared_ptr but you only have access to *this:
struct Node;
void process_node(const std::shared_ptr<Node> &);
struct Node : std::enable_shared_from_this<Node> // CRTP
{
std::weak_ptr<Node> parent;
std::vector<std::shared_ptr<Node>> children;
void add_child(std::shared_ptr<Node> child)
{
process_node(shared_from_this()); // Shouldn't pass `this` directly.
child->parent = weak_from_this(); // Ditto.
children.push_back(std::move(child));
}
};
The reason you can't just pass this directly instead of shared_from_this() is that it would break the ownership mechanism:
struct S
{
std::shared_ptr<S> get_shared() const { return std::shared_ptr<S>(this); }
};
// Both shared_ptr think they're the only owner of S.
// This invokes UB (double-free).
std::shared_ptr<S> s1 = std::make_shared<S>();
std::shared_ptr<S> s2 = s1->get_shared();
assert(s2.use_count() == 1);
Just as note:
CRTP could be used to implement static polymorphism(which like dynamic polymorphism but without virtual function pointer table).
#pragma once
#include <iostream>
template <typename T>
class Base
{
public:
void method() {
static_cast<T*>(this)->method();
}
};
class Derived1 : public Base<Derived1>
{
public:
void method() {
std::cout << "Derived1 method" << std::endl;
}
};
class Derived2 : public Base<Derived2>
{
public:
void method() {
std::cout << "Derived2 method" << std::endl;
}
};
#include "crtp.h"
int main()
{
Derived1 d1;
Derived2 d2;
d1.method();
d2.method();
return 0;
}
The output would be :
Derived1 method
Derived2 method
Another good example of using CRTP can be an implementation of observer design pattern. A small example can be constructed like this.
Suppose you have a class date and you have some listener classes like date_drawer, date_reminder, etc.. The listener classes (observers)
should be notified by the subject class date (observable) whenever a date change is done so that they can do their job (draw a date in some
format, remind for a specific date, etc.). What you can do is to have two parametrized base classes observer and observable from which you should derive
your date and observer classes (date_drawer in our case). For the observer design pattern implementation refer to the classic books like GOF. Here we only need to
highlight the use of CRTP. Let's look at it.
In our draft implementation observer base class has one pure virtual method which should be called by the observable class whenever a state change occurred,
let's call this method state_changed. Let's look at the code of this small abstract base class.
template <typename T>
struct observer
{
virtual void state_changed(T*, variant<string, int, bool>) = 0;
virtual ~observer() {}
};
Here, the main parameter that we should focus on is the first argument T*, which is going to be the object for which a state was changed. The second parameter
is going to be the field that was changed, it can be anything, even you can omit it, that's not the problem of our topic (in this case it's a std::variant of
3 fields).
The second base class is
template <typename T>
class observable
{
vector<unique_ptr<observer<T>>> observers;
protected:
void notify_observers(T* changed_obj, variant<string, int, bool> changed_state)
{
for (unique_ptr<observer<T>>& o : observers)
{
o->state_changed(changed_obj, changed_state);
}
}
public:
void subscribe_observer(unique_ptr<observer<T>> o)
{
observers.push_back(move(o));
}
void unsubscribe_observer(unique_ptr<observer<T>> o)
{
}
};
which is also a parametric class that depends on the type T* and that's the same object that is passed to the state_changed function inside the
notify_observers function.
Remains only to introduce the actual subject class date and observer class date_drawer. Here the CRTP pattern is used, we derive the date observable class from observable<date>: class date : public observable<date>.
class date : public observable<date>
{
string date_;
int code;
bool is_bank_holiday;
public:
void set_date_properties(int code_ = 0, bool is_bank_holiday_ = false)
{
code = code_;
is_bank_holiday = is_bank_holiday_;
//...
notify_observers(this, code);
notify_observers(this, is_bank_holiday);
}
void set_date(const string& new_date, int code_ = 0, bool is_bank_holiday_ = false)
{
date_ = new_date;
//...
notify_observers(this, new_date);
}
string get_date() const { return date_; }
};
class date_drawer : public observer<date>
{
public:
void state_changed(date* c, variant<string, int, bool> state) override
{
visit([c](const auto& x) {cout << "date_drawer notified, new state is " << x << ", new date is " << c->get_date() << endl; }, state);
}
};
Let's write some client code:
date c;
c.subscribe_observer(make_unique<date_drawer>());
c.set_date("27.01.2022");
c.set_date_properties(7, true);
the output of this test program will be.
date_drawer notified, new state is 27.01.2022, new date is 27.01.2022
date_drawer notified, new state is 7, new date is 27.01.2022
date_drawer notified, new state is 1, new date is 27.01.2022
Note that using CRTP and passing this to the notify notify_observers function whenever a state change occurred (set_date_properties and set_date here). Allowed us to use date* when overriding void state_changed(date* c, variant<string, int, bool> state) pure virtual function in the actual date_drawer observer class, hence we have date* c inside it (not observable*) and for example we can call a non-virtual function of date* (get_date in our case)
inside the state_changed function.
We could of refrain from wanting to use CRTP and hence not parametrizing the observer design pattern implementation and use observable base class pointer everywhere. This way we could have the same effect, but in this case whenever we want to use the derived class pointer (even though not very recomendeed) we should use dynamic_cast downcasting which has some runtime overhead.
Without referring to a book, can anyone please provide a good explanation for CRTP with a code example?
In short, CRTP is when a class A has a base class which is a template specialization for the class A itself. E.g.
template <class T>
class X{...};
class A : public X<A> {...};
It is curiously recurring, isn't it? :)
Now, what does this give you? This actually gives the X template the ability to be a base class for its specializations.
For example, you could make a generic singleton class (simplified version) like this
template <class ActualClass>
class Singleton
{
public:
static ActualClass& GetInstance()
{
if(p == nullptr)
p = new ActualClass;
return *p;
}
protected:
static ActualClass* p;
private:
Singleton(){}
Singleton(Singleton const &);
Singleton& operator = (Singleton const &);
};
template <class T>
T* Singleton<T>::p = nullptr;
Now, in order to make an arbitrary class A a singleton you should do this
class A: public Singleton<A>
{
//Rest of functionality for class A
};
So you see? The singleton template assumes that its specialization for any type X will be inherited from singleton<X> and thus will have all its (public, protected) members accessible, including the GetInstance! There are other useful uses of CRTP. For example, if you want to count all instances that currently exist for your class, but want to encapsulate this logic in a separate template (the idea for a concrete class is quite simple - have a static variable, increment in ctors, decrement in dtors). Try to do it as an exercise!
Yet another useful example, for Boost (I am not sure how they have implemented it, but CRTP will do too).
Imagine you want to provide only operator < for your classes but automatically operator == for them!
you could do it like this:
template<class Derived>
class Equality
{
};
template <class Derived>
bool operator == (Equality<Derived> const& op1, Equality<Derived> const & op2)
{
Derived const& d1 = static_cast<Derived const&>(op1);//you assume this works
//because you know that the dynamic type will actually be your template parameter.
//wonderful, isn't it?
Derived const& d2 = static_cast<Derived const&>(op2);
return !(d1 < d2) && !(d2 < d1);//assuming derived has operator <
}
Now you can use it like this
struct Apple:public Equality<Apple>
{
int size;
};
bool operator < (Apple const & a1, Apple const& a2)
{
return a1.size < a2.size;
}
Now, you haven't provided explicitly operator == for Apple? But you have it! You can write
int main()
{
Apple a1;
Apple a2;
a1.size = 10;
a2.size = 10;
if(a1 == a2) //the compiler won't complain!
{
}
}
This could seem that you would write less if you just wrote operator == for Apple, but imagine that the Equality template would provide not only == but >, >=, <= etc. And you could use these definitions for multiple classes, reusing the code!
CRTP is a wonderful thing :) HTH
Here you can see a great example. If you use virtual method the program will know what execute in runtime. Implementing CRTP the compiler is which decide in compile time!!! This is a great performance!
template <class T>
class Writer
{
public:
Writer() { }
~Writer() { }
void write(const char* str) const
{
static_cast<const T*>(this)->writeImpl(str); //here the magic is!!!
}
};
class FileWriter : public Writer<FileWriter>
{
public:
FileWriter(FILE* aFile) { mFile = aFile; }
~FileWriter() { fclose(mFile); }
//here comes the implementation of the write method on the subclass
void writeImpl(const char* str) const
{
fprintf(mFile, "%s\n", str);
}
private:
FILE* mFile;
};
class ConsoleWriter : public Writer<ConsoleWriter>
{
public:
ConsoleWriter() { }
~ConsoleWriter() { }
void writeImpl(const char* str) const
{
printf("%s\n", str);
}
};
CRTP is a technique to implement compile-time polymorphism. Here's a very simple example. In the below example, ProcessFoo() is working with Base class interface and Base::Foo invokes the derived object's foo() method, which is what you aim to do with virtual methods.
http://coliru.stacked-crooked.com/a/2d27f1e09d567d0e
template <typename T>
struct Base {
void foo() {
(static_cast<T*>(this))->foo();
}
};
struct Derived : public Base<Derived> {
void foo() {
cout << "derived foo" << endl;
}
};
struct AnotherDerived : public Base<AnotherDerived> {
void foo() {
cout << "AnotherDerived foo" << endl;
}
};
template<typename T>
void ProcessFoo(Base<T>* b) {
b->foo();
}
int main()
{
Derived d1;
AnotherDerived d2;
ProcessFoo(&d1);
ProcessFoo(&d2);
return 0;
}
Output:
derived foo
AnotherDerived foo
This is not a direct answer, but rather an example of how CRTP can be useful.
A good concrete example of CRTP is std::enable_shared_from_this from C++11:
[util.smartptr.enab]/1
A class T can inherit from enable_shared_from_this<T> to inherit the shared_from_this member functions that obtain a shared_ptr instance pointing to *this.
That is, inheriting from std::enable_shared_from_this makes it possible to get a shared (or weak) pointer to your instance without access to it (e.g. from a member function where you only know about *this).
It's useful when you need to give a std::shared_ptr but you only have access to *this:
struct Node;
void process_node(const std::shared_ptr<Node> &);
struct Node : std::enable_shared_from_this<Node> // CRTP
{
std::weak_ptr<Node> parent;
std::vector<std::shared_ptr<Node>> children;
void add_child(std::shared_ptr<Node> child)
{
process_node(shared_from_this()); // Shouldn't pass `this` directly.
child->parent = weak_from_this(); // Ditto.
children.push_back(std::move(child));
}
};
The reason you can't just pass this directly instead of shared_from_this() is that it would break the ownership mechanism:
struct S
{
std::shared_ptr<S> get_shared() const { return std::shared_ptr<S>(this); }
};
// Both shared_ptr think they're the only owner of S.
// This invokes UB (double-free).
std::shared_ptr<S> s1 = std::make_shared<S>();
std::shared_ptr<S> s2 = s1->get_shared();
assert(s2.use_count() == 1);
Just as note:
CRTP could be used to implement static polymorphism(which like dynamic polymorphism but without virtual function pointer table).
#pragma once
#include <iostream>
template <typename T>
class Base
{
public:
void method() {
static_cast<T*>(this)->method();
}
};
class Derived1 : public Base<Derived1>
{
public:
void method() {
std::cout << "Derived1 method" << std::endl;
}
};
class Derived2 : public Base<Derived2>
{
public:
void method() {
std::cout << "Derived2 method" << std::endl;
}
};
#include "crtp.h"
int main()
{
Derived1 d1;
Derived2 d2;
d1.method();
d2.method();
return 0;
}
The output would be :
Derived1 method
Derived2 method
Another good example of using CRTP can be an implementation of observer design pattern. A small example can be constructed like this.
Suppose you have a class date and you have some listener classes like date_drawer, date_reminder, etc.. The listener classes (observers)
should be notified by the subject class date (observable) whenever a date change is done so that they can do their job (draw a date in some
format, remind for a specific date, etc.). What you can do is to have two parametrized base classes observer and observable from which you should derive
your date and observer classes (date_drawer in our case). For the observer design pattern implementation refer to the classic books like GOF. Here we only need to
highlight the use of CRTP. Let's look at it.
In our draft implementation observer base class has one pure virtual method which should be called by the observable class whenever a state change occurred,
let's call this method state_changed. Let's look at the code of this small abstract base class.
template <typename T>
struct observer
{
virtual void state_changed(T*, variant<string, int, bool>) = 0;
virtual ~observer() {}
};
Here, the main parameter that we should focus on is the first argument T*, which is going to be the object for which a state was changed. The second parameter
is going to be the field that was changed, it can be anything, even you can omit it, that's not the problem of our topic (in this case it's a std::variant of
3 fields).
The second base class is
template <typename T>
class observable
{
vector<unique_ptr<observer<T>>> observers;
protected:
void notify_observers(T* changed_obj, variant<string, int, bool> changed_state)
{
for (unique_ptr<observer<T>>& o : observers)
{
o->state_changed(changed_obj, changed_state);
}
}
public:
void subscribe_observer(unique_ptr<observer<T>> o)
{
observers.push_back(move(o));
}
void unsubscribe_observer(unique_ptr<observer<T>> o)
{
}
};
which is also a parametric class that depends on the type T* and that's the same object that is passed to the state_changed function inside the
notify_observers function.
Remains only to introduce the actual subject class date and observer class date_drawer. Here the CRTP pattern is used, we derive the date observable class from observable<date>: class date : public observable<date>.
class date : public observable<date>
{
string date_;
int code;
bool is_bank_holiday;
public:
void set_date_properties(int code_ = 0, bool is_bank_holiday_ = false)
{
code = code_;
is_bank_holiday = is_bank_holiday_;
//...
notify_observers(this, code);
notify_observers(this, is_bank_holiday);
}
void set_date(const string& new_date, int code_ = 0, bool is_bank_holiday_ = false)
{
date_ = new_date;
//...
notify_observers(this, new_date);
}
string get_date() const { return date_; }
};
class date_drawer : public observer<date>
{
public:
void state_changed(date* c, variant<string, int, bool> state) override
{
visit([c](const auto& x) {cout << "date_drawer notified, new state is " << x << ", new date is " << c->get_date() << endl; }, state);
}
};
Let's write some client code:
date c;
c.subscribe_observer(make_unique<date_drawer>());
c.set_date("27.01.2022");
c.set_date_properties(7, true);
the output of this test program will be.
date_drawer notified, new state is 27.01.2022, new date is 27.01.2022
date_drawer notified, new state is 7, new date is 27.01.2022
date_drawer notified, new state is 1, new date is 27.01.2022
Note that using CRTP and passing this to the notify notify_observers function whenever a state change occurred (set_date_properties and set_date here). Allowed us to use date* when overriding void state_changed(date* c, variant<string, int, bool> state) pure virtual function in the actual date_drawer observer class, hence we have date* c inside it (not observable*) and for example we can call a non-virtual function of date* (get_date in our case)
inside the state_changed function.
We could of refrain from wanting to use CRTP and hence not parametrizing the observer design pattern implementation and use observable base class pointer everywhere. This way we could have the same effect, but in this case whenever we want to use the derived class pointer (even though not very recomendeed) we should use dynamic_cast downcasting which has some runtime overhead.
I have problem with my class/pointers.
I have two classes FirstClass and SecondClass.
FirstClass has two pointers:
MyClass *character1;
MyClass *character2;
I assign to these pointers later in my code but now i have my SecondClass where i also have 2 pointers:
MyClass *oldChar1;
MyClass *oldChar2;
I want to set oldChar to the same as indicated by character. I made a function in SecondClass with friend clause in FirstClass.
void SecondClass::setChars()
{
*oldChar1 = FirstClass::character1;
*oldChar2 = FirstClass::character2;
}
Result:
illegal reference to non-static member 'FirstClass::character1'
I dont get it :/ Somebody can help me??
There are a few approaches to do this.
A friend function shared in both classes (source).
The friend function has access to the data members of the class MyFirstClass and MySecondClass, but the friend function still needs to be told which instances of those classes to use (see this) e.g.
class MyClass {
};
class MySecondClass; //forward declaration for later
class MyFirstClass {
private:
MyClass *character1;
MyClass *character2;
public:
//friend function
friend void setChars(MyFirstClass& c1, MySecondClass& c2); //<---- friend function
};
class MySecondClass {
private:
MyClass *oldChar1;
MyClass *oldChar2;
public:
//friend function
friend void setChars(MyFirstClass& c1, MySecondClass& c2);
};
//define the friend function
void setChars(MyFirstClass& c1, MySecondClass& c2) {
c2.oldChar1 = c1.character1;
c2.oldChar2 = c1.character2;
}
int main() {
MyFirstClass c1;
MySecondClass c2;
setChars(c1,c2);
}
Friend Class.
Make MySecondClass a friend of MyFirstClass. MySecondClass will have method setChars which will take an instance of MyFirstClass as a parameter. e.g.
class MyClass {
};
class MySecondClass;
class MyFirstClass {
private:
MyClass *character1;
MyClass *character2;
public:
friend MySecondClass; //<----- friend class
};
class MySecondClass {
private:
MyClass *oldChar1;
MyClass *oldChar2;
public:
void setCharsUsingFriendClass(MyFirstClass& c1) {
oldChar1 = c1.character1;
oldChar2 = c1.character2;
}
};
int main() {
MyFirstClass c1;
MySecondClass c2;
c2.setCharsUsingFriendClass(c1);
}
And finally using 2 getter methods. I think this approach is better because it allows the classes to hide their implementation details (encapsulation).
class MyClass {
};
class MySecondClass;
class MyFirstClass {
private:
MyClass *character1;
MyClass *character2;
public:
//define getters to access the private members
MyClass* GetCharacter1() {return character1;}
MyClass* GetCharacter2() {return character2;}
};
class MySecondClass {
private:
MyClass *oldChar1;
MyClass *oldChar2;
public:
void setCharsUsingGetters(MyFirstClass& c1) {
oldChar1 = c1.GetCharacter1();
oldChar2 = c1.GetCharacter2();
}
};
int main() {
MyFirstClass c1;
MySecondClass c2;
c2.setCharsUsingGetters(c1);
}
i made the following code where data and process are two classes and i m trying to use the variables of the object of data class in the functions of process class by making them friend to the data class.
class data;
class process
{
public:
void rarea(data ob);
void carea(data ob);
};
void process::rarea(data ob)
{
int a;
a=ob.l*ob.b;
cout<<a;
}
void process::carea(data ob)
{
int a;
a=3.14*ob.r*ob.r;
cout<<a;
}
class data
{
int l,b,r;
public:
void input()
{
cin>>l>>b>>r;
}
friend void process::carea(data);
friend void process::rarea(data);
};
int main()
{
data d;
process p;
d.input();
p.carea(d);
p.rarea(d);
}
but the compiler is giving errors.
error:'ob' has incomplete type
error:forward declaration of data
The definitions of rarea and carea need access to the definition of data, or they won't know what one looks like.
Their declarations don't, so it will work if you just rearrange a little:
class data;
class process
{
public:
void rarea(data ob);
void carea(data ob);
};
class data
{
int l,b,r;
public:
void input()
{
cin>>l>>b>>r;
}
friend void process::carea(data);
friend void process::rarea(data);
};
void process::rarea(data ob)
{
//...
}
void process::carea(data ob)
{
//...
}
I have a class IDocument which serve as a interface for some classes. It has some abstracts methods (virtual ... = 0).
I would like to do such all subclasses also have to implement an operator for serialization:
In addition to the overloaded stream operators documented here, any Qt classes that you might want to serialize to a QDataStream will have appropriate stream operators declared as non-member of the class:
I'm not even sure how I would make an abstract operator, but how do I define it nonmember?
A non-member operator is a free function, pretty much like any other free function. For QDataStream, on operator<< would look like:
QDataStream& operator<<(QDataStream& ds, SomeType const& obj)
{
// do stuff to write obj to the stream
return ds;
}
In your case, you could implement your serialization like this (this is just one way of doing it, there are others):
#include <QtCore>
class Base {
public:
Base() {};
virtual ~Base() {};
public:
// This must be overriden by descendants to do
// the actual serialization I/O
virtual void serialize(QDataStream&) const = 0;
};
class Derived: public Base {
QString member;
public:
Derived(QString const& str): member(str) {};
public:
// Do all the necessary serialization for Derived in here
void serialize(QDataStream& ds) const {
ds << member;
}
};
// This is the non-member operator<< function, valid for Base
// and its derived types, that takes advantage of the virtual
// serialize function.
QDataStream& operator<<(QDataStream& ds, Base const& b)
{
b.serialize(ds);
return ds;
}
int main()
{
Derived d("hello");
QFile file("file.out");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << d;
return 0;
}