Devs.site

Declarations and definitions in C++

There are interpreted languages where a function or variable can go wherever you want with respect to the place from which they are referred. The interpreter will find them, even if declared after their invocation. It's not the case of C++, where the compiler must know the type of a variable before it is used or a function (and its parameters) before it is called.

If you have

    int main() {
        message();
    }

    void message() {
        cout << "Hello world";
    }

the compiler will complain about not knowing what message() function you are calling in main because it has to be declared first


Declaring is letting the compiler know crucial information required for compiling about a variable, function, class or namespace in those cases where they are invoked before they are actually implemented (defined)

Defining is where the actual variable, function, class or namespace is implemented (where it is assigned a value in the case of variable or where the functions have a body with the code that accomplishes their purpose)

In the case above, we must do a forward declaration of the message() function before the main function that uses it so that when the compiler finds its invocation, it already knows what type of function is that, if there are any parameters to send and what should it return.

    void message(); // this is a forward declaration

    int main() {
        message(); // now we know that this is a void function with no parameters
    }

    void message() { // this is the definition, where the actual function has its code
        cout << "Hello world";
    }

This is the simplest case where we declare a function before using it. Another case is when we have multiple source files and in one of them we need to call a function from another source file

source1.cpp

    void message(string text) {
        cout << text;
    }

main.cpp

    int main() {
        message("Hello world");
    }

How do we help the compiler know that the message()function called from main.cpp is defined in source1.cpp, is of void type and needs a string parameter? We add a header file where we declare it

source1.h

    void message(string); // declaration of the function

and then include this header in both source files (the one that defines it and the ones where it is called).

There is another case where we might have a global variable that is used across multiple source files but it is defined only in one. In this case we also use a header file but we need to use the extern keyword to let the compiler know that the variable is defined in some of the multiple source files.

source1.cpp

    #include "source1.h"
    #include "source2.h"

    void message(string text) {
        cout << text << ", " << name;
    }

source1.h

    void message(string); // declaration of the function

source2.cpp

    #include "source2.h"

    string name = "Anonymous"; // this is where we define the variable

    void setname(string newname) {
        name = newname;
    }

source2.h

    extern string name; // this is where we declare the existence of the variable
    void setname(string); // declaration of the function

main.cpp

    #include "source1.h"
    #include "source2.h"

    int main() {
        setname("Joshua");
        message("Hello");
    }

One last example is that of classes. When declaring classes in headers we do it like this:

greeting.h

    // class definition
    class Greeting {
        private:
            string _name; // private variable
        public:
            Greeting();
            void setname(string);
            void message(string);
    };

and this is how we define it

greeting.cpp

    #include "greeting.h"

    Greeting::Greeting() { // class constructor
        this->_name = "Anonymous";
    }

    void Greeting::setname(string newname) {
        this->_name = newname;
    }

    void Greeting::message(string text) {
        cout << text << ", " << this->_name;
    }

Having the class declared and defined, we can use it like this

main.cpp

    #include "greeting.h"

    int main() {
        Greeting newgreeting;
        newgreeting.setname("Alex");
        newgreeting.message("Howdy");
    }

And this is how you handle declarations and definitions. The compiler will make sure you do it right, so next time you see an error like this

'SOMETHING': identifier not found

you should make sure that you have declared your variable, function or class where it can see it before using it


Code

main.cpp

    #include <iostream>
    #include "source1.h"
    #include "source2.h"
    #include "greeting.h"

    int main()
    {
        Greeting newgreeting;
        newgreeting.setname("Alex");
        newgreeting.message("Howdy");
    }

source1.cpp

    #include "source1.h"
    #include "source2.h"

    void message(std::string text) {
        std::cout << text << ", " << name;
    }

source2.cpp

    #include "source2.h"

    std::string name = "Anonymous"; // this is where we define the variable

    void setname(std::string newname) {
        name = newname;
    }

greeting.cpp

    #include "greeting.h"

    Greeting::Greeting() { // class constructor
        this->_name = "Default";
    }

    void Greeting::setname(std::string newname) {
        this->_name = newname;
    }

    void Greeting::message(std::string text) {
        std::cout << text << ", " << this->_name;
    }

source1.h

    #pragma once

    #include <string>
    #include <iostream>

    void message(std::string);

source2.h

    #pragma once

    #include <string>

    extern std::string name; // this is where we declare the existence of the variable

    void setname(std::string); // declaration of the function

greeting.h

    #pragma once
    #include <string>
    #include <iostream>

    class Greeting {
    private:
        std::string _name = "Anonymous"; // private variable
    public:
        Greeting();
        void setname(std::string);
        void message(std::string);
    };

Requirements

Any C++ compiler will do the job of running this code


Instructions

Copy and paste the code, run and watch the results

0 comments

Specify your e-mail if you want to receive notifications about new comments and replies