0

I'm confused about how to define and declare my variables and functions across multiple files WITHOUT resorting to global variables. Let's say I wanted to have separate header and source files declaring and defining variables and functions outside of 'main.cpp', to be used in 'main.cpp'.

EDIT: Apologies for my unclear example, but there will only ever be one balloon. I don't want balloon to be an object. It's just to hold some variables and functions.

//balloon.h
bool inflated = true;
void pop();

-

//balloon.cpp
#include "balloon.h"
void pop()
{
    inflated = false;
}

-

//main.cpp
#include "balloon.h"
int main()
{
    pop();
    return 0;
}

If I do this it gives me errors for having multiple definitions of 'inflated', and that it was first declared in 'balloon.cpp'.

If I use 'extern', it works, but gives me warnings about initializing and declaring 'inflated' in 'balloon.h'.

If I decide not to define inflated in balloon.h, it gives me errors about an undefined reference to 'inflated'.

What is the standard way of going about this? Am I missing some key information of variable/function declaration/definition across multiple files?

Willy Goat
  • 1,175
  • 2
  • 9
  • 24

3 Answers3

1

Straight away it should be

//balloon.h
extern bool inflated;
void pop();

//balloon.cpp
#include "balloon.h"

bool inflated = true;

void pop() {
    inflated = false;
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
0

There is no "standard" way, but apparently what you're aiming for is like a single logical object with operations: some functions that operate on some common shared variables.

That was the original module concept of e.g. C and Modula-2.

In C one declared the variables as static in the implementation file, in order to not have their names exposed to the linker. This is called internal linkage. In C++ this use of static is deprecated, and instead one should preferentially use an anonymous namespace:

balloon.h

#pragma once
auto is_inflated() -> bool;
void inflate();

balloon.cpp

#include "ballon.h"

namespace {
    bool inflated = true;
}  // namespace anon

auto is_inflated() -> bool { return ::inflated; }
void inflate() { ::inflated = true; }

But instead of this old-fashioned module-as-a-logical-variable, consider defining a class.

That's what classes are for.


Disclaimer: code untouched by compiler's hands.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
0

If you don't want to use global variables, then create class to do the OOP style.

class A 
{
public:
bool inflated = true;
void pop();
}

You can separate specification and implementation like you did in question, it would look like this:

void A::pop()
{
   bool inflated = false;
}

And then include .h file in main and create an object of a class: A* a = new A(); For more reference go here http://www.cplusplus.com/doc/tutorial/classes/

Oleksandr Verhun
  • 814
  • 1
  • 8
  • 23