kapil kapil - 2 months ago 9
C++ Question

How to write a class library in c++ like the one we write for functions

Suppose we need to write a library of functions which we intend to use in our programs, then we could write it by the following way.

In a .h file we declare the function (mylibrary could be any file name we wish)
Assuming sum is the function we wish to have in our library

int sum(int x, int y);


Then we will have a .cpp file which will define the function as follows :

#include "mylibrary.h"

int sum(int x, int y){ return x+y; }


Now we we wish to use this function in our programs, say myprog.cpp, we could use like this :

#include
#include "mylibrary.h"

int main()
{
cout<<sum(10,20)<<endl;
return 0;
}


My question is that can we do something similar for classes as we did for functions, i.e.

Can we declare classes in a .h file like :

class X;
class Y;


Then define the class in .cpp like :

#include"myclasses.h"
class X
{
public:
int m;
};

class Y
{
public:
int n;
};


and then use these classes in our program, say myprog.cpp, like this :

#include"myclasses.h"

int main()
{
class X myX;
myX.m = 0;
return 0;
}


I tried this and got Error aggregate 'X myX' has incomplete type and cannot be defined.

If I put entire definition in myclasses.h file, then it runs fine without errors.

I wish to know if we can write a class library following the blueprint for function library.

What I have tried:

If I put entire definition in myclasses.h file, then it runs fine without errors.

I wish to know if we can write a class library following the blueprint for function library.
enter code here

Answer

You can put all of the methods in the .cpp file, but you have to have a "complete" declaration of the class in the header file. That is, you can do this:

// X.h
#ifndef _X_H
#define _X_H

class X {
    int data;
    void internal_method();

public:
    void foo();
    void bar();
};

#endif // X.h

and then you can define X::foo, X::bar, and X::internal_method in a .cpp file, but you can't do this or anything like it:

// X.h
#ifndef _X_H
#define _X_H

// This code is incorrect and will not even compile
class X;
public void X::foo();
public void X::bar();

#endif // X.h

This is a fundamental limitation of C++, and yes, it means you can't change the data members or add or remove methods - even private methods - without recompiling everything. The pimpl hack works around this, but has its own problems.

(You may have noticed that class X; all by itself is a valid thing to write. That is an "incomplete" declaration of the class, which allows you to declare things involving pointers and references to X objects, but not X objects themselves. For instance, this header file is valid:

// Y.h
#ifndef _Y_H
#define _Y_H

class X;

class Y {
   X& ex;

public:
    Y(X& ex) : ex(ex) {}

    void foo();
    void bar(X& fx);
};

#endif // Y.h

This can be a useful thing to do, for instance to cut down on the number of header files that need to include other header files, and to break mutual dependency loops (imagine if class X had some methods that took reference-to-Y arguments, without a feature like this you couldn't write that at all).)