i have Point3D class in my project.
to create an object of Point3D i have added a cpp file & a header file as follows:
CreatePoint.h
#include "stdafx.h"
#pragma once
#include "Point3D.h"
//*******************************************************************
int counter = 0;
int size = 50;
Point3D **point;
//*******************************************************************
void create_array(int);//this will be called in main & pass 50//this is the method to create an array of pointers to Point3D
//*******************************************************************
void resize();//this increases the size of array if size - 5 elements are filled & increases size by 25
//*******************************************************************
Point3D *get_point(int);//this returns the pointer according to the index
//*******************************************************************
int get_index(Point3D *);//this returns the index of a point
//*******************************************************************
void move_point(int, int);//this interchanges the memory locations of 2 points
//*******************************************************************
void del_point(Point3D *);//this makes NULL value to the passed point
//*******************************************************************
void destruct_point();//this is called when the program ends by me
& the cpp file is:
#include "stdafx.h"
#include "CreatePoint.h"
//*******************************************************************
void create_array(int s)
{
point = new Point3D *[s];
for (int i = 0; i<s; i++)
{
point[i] = NULL;
}
}
//*******************************************************************
void resize()
{
Point3D **copy = new Point3D *[size];
for(int i = 0; i<size; i++)
{
copy[i] = point[i];
}
delete [] point;
size += 25;
create_array(size);
for(int i = 0; i<(size - 25); i++)
{
point[i] = copy[i];
}
delete [] copy;
}
//*******************************************************************
Point3D *get_point(int i)
{
if((size - counter) == 5)
resize();
return point[i];
}
//*******************************************************************
int get_index(Point3D *p)
{
for(int i = 0; i<size; i++)
{
if(point[i] == p)
return i;
}
return -1;
}
//*******************************************************************
void move_point(int a, int b)
{
Point3D *apt = get_point(a);
Point3D *bpt = get_point(b);
Point3D *t = new Point3D;
t = apt;
apt = bpt;
bpt = t;
delete t;
}
//*******************************************************************
void del_point(Point3D *p)
{
int d = get_index(p);
move_point(d, counter - 1);
point[counter - 1] = NULL;
}
//*******************************************************************
void destruct_point()
{
delete [] point;
point = NULL;
}
i am getting some linking errors:
stdafx.obj : error LNK2005: "class Point3D * * point" (?point##3PAPAVPoint3D##A) already defined in CreatePoint.obj
1>stdafx.obj : error LNK2005: "int counter" (?counter##3HA) already defined in CreatePoint.obj
1>stdafx.obj : error LNK2005: "int size" (?size##3HA) already defined in CreatePoint.obj
1>C:\Documents and Settings\SUMIT & AMIT\my documents\visual studio 2010\Projects\Maths\Debug\Maths.exe : fatal error LNK1169: one or more multiply defined symbols found
can anybody please help me!!!
also, any suggestions on the code will be appreciated :)
THANKS A LOT FOR READING MY POST
In header file use extern when declaring the variables, as:
//CreatePoint.h
extern int counter; //it is only a declaration
extern int size; //it is only a declaration
extern Point3D **point; //it is only a declaration
And in the source file, define and initialize them as:
//CreatePoint.cpp
#include "CreatePoint.h"
int counter = 0; //it is the definition
int size = 50; //it is the definition
Point3D **point; //it is the definition
You get multiple definitions error, because you include CreatePoint.h more than one .cpp file which defines the same variables more than once. Using extern in header file, avoids this, because it doesn't define them, it simply declares them, while the actual definition goes in the .cpp file.
The keyword extern tells the compiler to look for the definition elsewhere. The extern statements in the header are only declaration of the variables.
You are declaring & defining these variables directly in a header file. Every CPP file that includes this H file will get it's own definition of it, which is in violation of the One Definition Rule.
You need to change your design so that there is only one definition. You could make them extern in the H file:
CreatePoint.H
extern int counter;
extern int size;
extern Point3D **point;
...and then define them in the CPP file:
CreatePoint.CPP
int counter = 0;
int size = 50;
Point3D** point = 0;
Global variables are generally bad, however. You should redesign your code so as to not use them.
You need to declare variables as extern in the header because they are outside a function block. If they were declared inside a function, they would be considered automatic
Related
I'm making a heap class to be importable with heap.h and my constructors including bool types do not work, yet every other constructor and function imported works.
Here is what's in heap.h:
#ifndef __HEAP_INCLUDED__
#define __HEAP_INCLUDED__
#include <iostream>
#include <vector>
using namespace std;
class heap{
int capacity;
bool isMinHeap; //1 is min heap -- ascending order
vector<int> * content;
public:
heap();
heap(bool t);
heap(vector<int> * input);
heap(vector<int> * input, bool t);
void print();
void prettyPrint();
int parent(int i);
int leftChild(int i);
int rightChild(int i);
int size();
int getMax();
void insert(int data);
void heapifyDown(int index);
void heapifyUp(int index);
int invalidChild(int index);
int deleteMax();
int deleteMin();
bool minDir();
int at(int index);
};
vector<int> * heapSort(vector<int> * input);
void swap(vector<int> * vec, int a, int b);
#endif
Here are the defined constructors in heap.cpp. Note, all constructors work fine when I add a main to this file to test stuff:
class heap{
vector<int> * content;
int capacity = 256;
bool isMinHeap; //1 is min heap -- ascending order
public:
heap(){
content = new vector<int>;
isMinHeap = 0;
}
heap(bool t){
content = new vector<int>;
isMinHeap = t;
}
heap(vector<int> * input){
content = input;
isMinHeap = true;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
heap(vector<int> * input, bool t){
content = input;
isMinHeap = t;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
//other functions below
}
The constructors with bool do not work in main.cpp, which has #include "heap.h" at the top. The files are all in the same directory and I am compiling with this command: g++ heap.cpp main.cpp -o main. Why do two of my constructors not work?
The error I see is
/usr/bin/ld: /tmp/ccwomODk.o: in function `main':
main.cpp:(.text+0x4e2): undefined reference to `heap::heap(bool)'
collect2: error: ld returned 1 exit status
-Wall does not elaborate on the issue. I'm pretty sure the issue is with my linking somewhere because the constructors work inside of heap.cpp when I use them in there.
What you are doing with the class in the .cpp file is wrong. You are not allowed to define the class twice. There must only be one class heap { /*...*/ }; in the program (but it may be included in multiple .cpp files). Otherwise the one-definition-rule (ODR) is violated and the program has undefined behavior.
So remove everything you are showing from heap.cpp.
To define the constructors of heap in the heap.cpp file, you need to use this syntax:
#include "heap.h"
heap::heap() {
/*...*/
}
heap::heap(bool t) {
/*...*/
}
//...
and so on. The other member functions must be defined in a similar way, e.g.:
void heap::print() {
/*...*/
}
Furthermore, if you want to have a default member initializer as in
int capacity = 256;
add it in the declaration in the .h file instead.
I also want to add that having a pointer-to-std::vector as member is almost surely a wrong approach as well, but out-of-scope for the question.
When you declare a program element such as a class, function, or
variable, its name can only be "seen" and used in certain parts of
your program. The context in which a name is visible is called its
scope. For example, if you declare a variable x within a function, x
is only visible within that function body.
It seems you broke ODR rule so bad. Your class members including constructors has no body declared in the source file(heap.cpp).
Use '::' to make class members have a body:
//heap.cpp
"heap.h"
heap::heap()
{
}
heap:heap(vector<int> * input, bool t)
{
}
int heap::parent(int i)
{
return i;
}
// this is how you create a body for function that are class members
// the same should be done for all other functions
I have been having a lot of issues with header files, and now it seems that the vector that is declared in my header file, Polynomial.hpp, is not being recognized in Polynomial.cpp. I have already included std:: which seems to be a common mistake, so I don't know where to go from here.
Header file:
#ifndef POLYNOMIAL_HPP
#define POLYNOMIAL_HPP
#include<vector>
#include"term.hpp"
class Polynomial {
private:
std::vector<Term> vect;
public:
Polynomial();
~Polynomial();
void add(Term t);
void print();
Polynomial combineLikeTerms();
};
#endif
cpp File:
#include "term.hpp"
#include "Polynomial.hpp"
#include<iostream>
#include<map>
using namespace std;
void add(Term t) {
vect.push_back(t);
}
void print() {
for(int i = 0; i < vect.size(); i++) {
cout << vect[i].toString();
}
}
Polynomial combineLikeTerms() {
Polynomial poly;
map<int, int> combinedPoly;
for(int j = 0; j < vect.size(); j++)
{
combinedPoly.insert(pair<int, int>(vect[j].getExponent(), vect[j].getCoefficient());
}
for(map<int,int>::iterator itr = combinedPoly.begin(); itr != combinedPoly.end(); itr++) {
Term newTerm(itr->second, "x", itr->first);
poly.add(newTerm);
}
return poly;
}
Error (1/6):
Polynomial.cpp:9:5: error: use of undeclared identifier 'vect'
vect.push_back(t);
In Polynomial.cpp you are defining new functions instead of member functions. Change the definitions to use the class name like
void Polynomial::add(Term t) {
vect.push_back(t);
}
Your void add(Term T) in Polynomial.cpp is not the member function of the Polynomial.
You must implement this function as member of Polynomial like this
void Polynomial::add(Term T){
...
}
I think this is a syntax error. First, you defined the add method in the Polynomial class of the header file, but the CPP file did not add the class scope, which caused this problem. So you should adjust your code like this:
void Polynomial::add(Term t) {
vect.push_back(t);
}
The root cause of this problem is that the methods of the class only work within the scope of the class, and if there is a function with the same name inside the class, it will lead to a naming conflict. Therefore, the root cause of this problem is not the reference error of the vector file.
The issue is that instead of defining the members add and print of the class Polynomial, you are defining functions in global scope completely unrelated to the class Polynomial
Make changes in the function definition of void add(Term) and void print() to void Polynomial::add(Term) and void Polynomial::print().
#include "term.hpp"
#include "Polynomial.hpp"
#include<iostream>
#include<map>
using namespace std;
void Polynomial::add(Term t) { // change here
vect.push_back(t);
}
void Polynomial::print() { //change here
for(int i = 0; i < vect.size(); i++) {
cout << vect[i].toString();
}
}
Polynomial combineLikeTerms() {
Polynomial poly;
map<int, int> combinedPoly;
for(int j = 0; j < vect.size(); j++)
{
combinedPoly.insert(pair<int, int>(vect[j].getExponent(), vect[j].getCoefficient());
}
for(map<int,int>::iterator itr = combinedPoly.begin(); itr != combinedPoly.end(); itr++) {
Term newTerm(itr->second, "x", itr->first);
poly.add(newTerm);
}
return poly;
}
I am getting an error message saying the use of undeclared identifier 'IntQueue' in vscode and I cannot figure out what is wrong.
I have tried renaming the file but still does not work. I created a separate header file that has the class defined and I included the header file in the main cpp file that has all the constructors defined. But I cannot figure out a way to solve the issue.
//This is the IntQueue.h header file
#ifdef _IntQueue_
#define _IntQueue_
#include<iostream>
#include<fstream>
using namespace std;
class IntQueue {
int* numbers;
int size;
int front;
int back;
public:
IntQueue (unsigned int n);
IntQueue();
~IntQueue();
int getSize() {return size;}
int getFront() {return front;}
int getBack() {return back;}
void incSize();
void pop();
int frontNumber();
void push(int i);
void reverse();
};
#endif
//This is the IntQueue.cpp file (incomplete)
#include "IntQueue.h"
IntQueue::IntQueue (unsigned int n) {
size = n;
numbers = new int[size];
front = 0;
back = 0;
}
IntQueue::IntQueue() {
size = 100;
front = 0;
back = 0
numbers = new int [size];
}
You need to change
#ifdef _IntQueue_
To
#ifndef _IntQueue_
When your .cpp file #include's your .h file, _IntQueue_ has not been declared yet, so the #ifdef skips the entire content of the .h file, and so the compiler doesn't know anything about your IntQueue class.
class1.cpp
int a=10; int b=5; int c=2;
//for this array[a][b][c]
int*** array=new int**[a];
for(int i =0; i<a; i++)
{
array[i] = new int*[b];
for(int k =0; k<b; k++)
{
array[i][k] = new int[c];
}
}
how can i use this array in other .cpp files ?
Instead of manually allocating an array you should at least use a std::vector. What you would do is have a header file that contains
extern std::vector<std::vector<std::vector<int>>> data;
that you will include in all the cpp files you wish to share the vector with and then in a single cpp file have
std::vector<std::vector<std::vector<int>>> data = std::vector<std::vector<std::vector<int>(a, std::vector<std::vector<int>>(b, std::vector<int>(c)));
and now you will have a global object that is shared and it has a managed lifetime.
You shouldn't really use a nested vector though. It can scatter the data in memory so it isn't very cache friendly. You should use a class with a single dimension vector and pretend that it has multiple dimensions using math. A very basic example of that would look like
class matrix
{
std::vector<int> data;
int row; // this really isn't needed as data.size() will give you rows
int col;
int depth;
public:
matrix(int x, int y, int z) : data(x * y * z), row(x), col(y), depth(z) {}
int& operator()(int x, int y, int z) { return data[x + (y * col) + (z * col * depth)]; }
};
and then the header file would be
extern matrix data;
and a single cpp file would contain
matrix data(a, b, c);
Prefer std::array or std::vector to raw arrays. You had constant dimensions so use std::array.
Declare it in header file:
// header.h
#pragma once // or use multiple inclusion guards with preprocessor
#include <array>
const int a = 10;
const int b = 5;
const int c = 2;
using Array3D = std::array<std::array<std::array<int,c>,b>,a>;
extern Array3D array3d; // extern indicates it is global
Define it in cpp file:
// class1.cpp
#include "header.h"
Array3D array3d;
Then include the header wherever you want to use it.
// main.cpp
#include "header.h"
int main()
{
array3d[3][2][1] = 42;
}
I am not sure I have understood what exactly you mean but simply :
class1 obj1;
obj1.array[i][j][k] // assuming you make the array public and already initialized in the constructor(and dont forget to delete it in the destructor)
I am getting the error "error: Invalid use of AppleFarmer::AppleFarmer. I do not know why I am getting this error since I am not trying to pass any input into my Constructor. Is it possible I have an issue with my .h file? What am i doing wrong to get this error?
I have three different files, and I may also be having an issue with linking the code together as I am doing #include for a .cpp file. I am not sure if my code works aside from this error, but I am stuck on this error.
appleFarmerMain.cpp
#include<iostream>
#include "appleFarmer.cpp"
int main(){
AppleFarmer m;
int harvest;
int demand;
m.AppleFarmer();
while(m.endOfMonth()==false){
cout<<"Enter a harvest amount:"<<endl;
cin>>harvest;
m.harvestApples(harvest);
cout<<"Enter a demand:"<<endl;
cin>>demand;
m.sellApples(demand);
cout<<"Apple Inventory: "<<m.getInventory()<<endl;
m.updateCurrentDay();
}
return 0;
}
appleFarmer.cpp
#include "appleFarmer.h"
#include "<iostream>
using namespace std;
AppleFarmer::AppleFarmer(){
for(int i=0;i<30;i++){
sales[i]=0;
harvest[i]=0;
}
}
bool AppleFarmer::sellApples(int demand){
if(demand<= inventory){
sales[currentDay]=demand;
inventory=inventory-demand;
}
else{
sales[currentDay]=0;
}
}
void AppleFarmer::harvestApples(int dayHarvest){
harvest[currentDay]= dayHarvest;
inventory=inventory+dayHarvest;
}
bool AppleFarmer::endOfMonth(){
if (currentDay=maxDays){
return true;
}
else{
return false;
}
}
int AppleFarmer::updateCurrentDay(){
currentDay=currentDay+1;
}
int AppleFarmer::getInventory(){
return inventory;
}
double AppleFarmer::calculateAverageHarvest(){
}
double calculateAverageSales(){
}
void AppleFarmer::printSales(){
}
void AppleFarmer::printHarvest(){
}
appleFarmer.h
#ifndef APPLEFARMER_H
#define APPLEFARMER_H
class AppleFarmer
{
public:
AppleFarmer();
bool sellApples(int);
void harvestApples(int);
bool endOfMonth();
int updateCurrentDay();
int getInventory();
double calculateAverageHarvest();
double calculateAverageSales();
void printSales();
void printHarvest();
private:
int sales[30];
int harvest[30];
int maxDays = 30;
int currentDay = 0;
int inventory = 0;
};
#endif
In C++ you don't call the constructor on an object. That happens at object creation time. The line
m.AppleFarmer();
isn't needed. The constructor is implicitly called here:
AppleFarmer m;
You need to include appleFarmer.h instead of appleFarmer.cpp because the header file (with .h extension) contains the declaration while the .cpp file contains the implementation.
Then you need also to delete m.AppleFarmer(); because the constructor is called during the declaration (AppleFarmer m text line).