0

I am a newcomer to C++. I am losing my mind over this issue (I have checked and tried other solutions from people having this very issue on Stack Overflow, yet for some reason I am unable to resolve it). I have the following files -

stdafx.h

#ifndef STDAFX_H
#define STDAFX_

#endif /* STDAFX_H */

#pragma once

#include <iostream>
#include <cstdlib>
#include <cmath>

geometry.h

#ifndef GEOMETRY_H
#define GEOMETRY_H



#endif /* GEOMETRY_H */

#pragma once

double PI = 3.1415;

class Circle    {
public:
    double radius;
    double area() const;
    double circumference() const;
};

geometry.cpp

#include "geometry.h"

double Circle::area() const {
    return PI*radius*radius;
}

double Circle::circumference() const {
    return 2*PI*radius;
}

main.cpp

#include "stdafx.h"
#include "geometry.h"

using namespace std;

int main() {
    Circle c;
    c.radius = 2.0;
    cout << c.area();
    cout << c.circumference();
}

The error I am getting is -

> cd '/Users/arpanganguli/NetBeansProjects/Chapter8'
/usr/bin/make -f Makefile CONF=Debug
"/Library/Developer/CommandLineTools/usr/bin/make" -f nbproject/Makefile- 
Debug.mk QMAKE= SUBPROJECTS= .build-conf
"/Library/Developer/CommandLineTools/usr/bin/make"  -f nbproject/Makefile- 
Debug.mk dist/Debug/GNU-MacOSX/chapter8
mkdir -p dist/Debug/GNU-MacOSX
g++     -o dist/Debug/GNU-MacOSX/chapter8 build/Debug/GNU-MacOSX/geometry.o 
build/Debug/GNU-MacOSX/main.o 
duplicate symbol _PI in:
build/Debug/GNU-MacOSX/geometry.o
build/Debug/GNU-MacOSX/main.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see 
invocation)
make[2]: *** [dist/Debug/GNU-MacOSX/chapter8] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

I don't understand what I am doing wrong? I am using Netbeans 10 on MacOS (if this information is helpful). I believe what the error is trying to tell me is that I am linking the same files twice, but if I don't like main.cpp and geometry.cpp through geometry.h, I will not be able to call the function in main.cpp. Can someone please help?

  • 1
    Move `double PI = 3.1415;` to "geometry.cpp" or make it a member of the `Circle` class. – 001 Oct 15 '18 at 15:05
  • Ah brilliant! Thanks! That worked! I have a follow-up question - why is it wrong to put PI in the geometry.h file? And say, if I have to create another .h and .cpp file that uses PI, would I need to still define PI in the cpp file? I thought defining it in geometry.h file and making it public was enough? –  Oct 15 '18 at 15:23

1 Answers1

0

You can't define a variable more than once. You include the header file in both geometry.cpp and main.cpp which causes it to be defined twice. As I mentioned in the comments, you can move the definition to the "geometry.cpp" file. If you want to use it in some other file, declare it in geometry.h as extern double PI; and still define it in geometry.cpp.

geometry.h

#pragma once

// Tell the compiler "this var exists, but in another file"
extern double PI;

class Circle    {
public:
    double radius;
    double area() const;
    double circumference() const;
};

geometry.cpp

#include "geometry.h"

// It is defined here
double PI = 3.1415;

double Circle::area() const {
    return PI*radius*radius;
}

double Circle::circumference() const {
    return 2*PI*radius;
}

Assuming the value of Pi never changes, you could also make it a const variable. Then you can go back to defining it in "geometry.h"

const double PI = 3.1415;

Or, to avoid a global variable altogether, make it a member of the Circle class:

class Circle    {
public:
    const double PI = 3.1415;
    double radius;
    double area() const;
    double circumference() const;
};

There's more to it than I can cover here. There are plenty of good C++ books listed here: The Definitive C++ Book Guide and List

001
  • 13,291
  • 5
  • 35
  • 66