Redefinition/Previous definition of struct

I've googled, searched, tried different things, and I'm stuck. Learning C++, and one of the exercises is to pass a struct to a function. I've done that, but I am now trying to pass it to a function contained in a header file. I get these errors and I don't quite understand how to fix it.

adStruct.cpp:7:8: error: redefinition of 'struct Advertizing'
In file included from C:\Users\james\Desktop\NoteP_C++\adStruct.cpp:2:0:
dailyIncome.h:5:8: error: previous definition of 'struct Advertizing'

adStruct.cpp file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include "dailyIncome.h"  //looks like have to redeclare variables??


using namespace std;

struct Advertizing
{
	int adShown;
	float userClickPercent;
	float avgPerClick;
	float dailyIncome;
};


float dailyIncome(Advertizing user1);
/**{
	user1.dailyIncome = user1.adShown * user1.userClickPercent * user1.avgPerClick;
	return user1.dailyIncome;
}*/
	

int main (){

struct Advertizing user1;
user1.adShown = 0;
user1.userClickPercent = 0;
user1.avgPerClick = 0;
user1.dailyIncome = 0;

	
	cout << "How many ads did you show today?"  << endl;
	cin >> user1.adShown;
	
	cout << "What percentage of users clicked on ads?"  << endl;
	cin >> user1.userClickPercent;
	
	cout << "What was the average earned per click?"  << endl;
	cin >> user1.avgPerClick;
	
user1.dailyIncome = dailyIncome(user1);
cout << "Todays income is "  <<  user1.dailyIncome <<  endl;
	
cin.clear();
cin.ignore(255, '\n');
cin.get();
return 0;
}


and the header file
dailyIncome.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef _DAILYINCOME_H
#define _DAILYINCOME_H


struct Advertizing
{
	int adShown;
	float userClickPercent;
	float avgPerClick;
	float dailyIncome;
};

float findDailyIncome(Advertizing user1)
{
	user1.dailyIncome = user1.adShown * user1.userClickPercent * user1.avgPerClick;
	return user1.dailyIncome;
	
}
#endif 


So you can see the section of code in comment blocks - that works. Using the headers does not, but it feel sooooo close.

Thanks.
Remove lines 5 - 22 in the adStruct.cpp file.

You need to understand what happens when you include a file. The entire contents of the include file are placed in the .cpp file as if the 2 had been concatenated. Hence the compiler errors.

A better way of doing things is to make the Advertizing struct a class, with the findDailyIncome function being a class function. In C++ struct & class are almost the same thing, the only difference is that structs have public access by default.

The header file has the declaration of the class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef _ADVERTIZING_H
#define _ADVERTIZING_H


class Advertizing {
private:
	int m_adShown;  //A convention to start member names with m_
	float m_userClickPercent;
	float m_avgPerClick;
	float m_dailyIncome;
public:
        Advertizing();  //default constructor - you can overload this to take arguments to build the obj
       
        ~Advertizing(); //default destructor - leave this as is

         Advertizing(int adShown, float userClickPercent, float m_avgPerClick ); //initialises member variables
        findDailyIncome();
};

#endif  


The .cpp file has the code for each member function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Advertizing.cpp

Advertizing::Advertizing() {}

Advertizing::~Advertizing() {}

Advertizing::Advertizing(int adShown, float userClickPercent, float m_avgPerClick ){
//initialise member variables
     m_adShown = adShown;
     m_userClickPercent = userClickPercent;
     m_avgPerClick = avgPerClick;
}

float Advertizing::findDailyIncome() {

      return m_adShown * m_userClickPercent * m_avgPerClick;
}


Now for main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include "Advertizing.h" //use the class name for naming files

using namespace std; //this is bad, it pollutes global namespace with heaps of things from std
//do this instead:
using std::cin;
using std::cout;
using std::endl;
//or put std:: before each std thing

int main (){

Advertizing user1; //the object

//input variables
int adShown = 0;
float userClickPercent 0.0;
float avgPerClick = 0.0;
float dailyIncome = 0.0;

	cout << "How many ads did you show today?"  << endl;
	cin >> adShown;
	
	cout << "What percentage of users clicked on ads?"  << endl;
	cin >> userClickPercent;
	
	cout << "What was the average earned per click?"  << endl;
	cin >> userClickPercent;

//call constructor

user1(adShown, userClickPercent, userClickPercent);
	
user1.dailyIncome = dailyIncome(user1);

cout << "Todays income is "  <<  user1.dailyIncome() <<  endl;
	
cin.clear();
cin.ignore(255, '\n');
cin.get();
return 0;
}


Hope this helps, and you can see how organised it is. Some important points are that there is no code in the header file, so it can be reused in lots of places without causing chaos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Advertizing::Advertizing(int adShown, float userClickPercent, float m_avgPerClick ):
   m_adShown(adShown), //initialization
   userClickPercent(userClickPercent) //no need for prefix
{
//this is assignment (after initialization)
     m_avgPerClick = avgPerClick;
}

float Advertizing::findDailyIncome() const{ //const correctness is important
      return m_adShown * m_userClickPercent * m_avgPerClick;
}

//call constructor
//user1(adShown, userClickPercent, userClickPercent);
//you can't call a constructor if the object is already constructed
Advertizing user1(adShown, userClickPercent, userClickPercent); //remove line 13 
You could use the default destructor that the compiler provides. For that, don't declare a destructor in your class.
Thank you,

Understanding concatenated is almost more help. Haven't got to classes yet, I'm at a real basic level. Took Java though so that makes allot of sense.
Topic archived. No new replies allowed.