When do you use which method to get variables from another file? - c++

I am currently learning C++ and found that there are at least two ways using variables defined in other files. However I do not understand really, when to use what method.
For example:
I have writte in "h1.h":
extern int k;
and "a2.cpp" writes:
#include "a2.h"
#include "h1.h"
int k = 42;
int k2 = 43;
Then I can reference k in my main.cpp with:
#include "main.h"
#include "a1.h"
#include "h1.h"
#include <iostream>
Main::Main() {}
int main() {
std::cout << k << std::endl;
}
However if I want to use k2 in main.cpp I could simply write a getter/setter method, thereby I would avoid having to use extern in a common included header file.
I would like to know: What are other ways to access variables from other files? When do you use which method (and why )?

You expose k as a function, or not at all, not as a variable.
"h1.h":
int k();
void k2(int &);
"h1.cpp":
int k() { return 42; }
void k2(int & value) { value = 43; }
"main.cpp"
#include "h1.h"
#include <iostream>
int main () {
std::cout << k() << std::endl;
int any_name;
k2(any_name);
std::cout << any_name << std::endl;
}

Related

C++ - Can I use extern and const at the same time with several files?

The thing is that I am trying to have a global constant variable for all the .hand .cpp files, but when I do this I got the error:
array bound is not an integer constant before ‘]’ token
I do not understand this because Z is a constant. When I do this with just one file it works. What am I doing wrong?
Number.h
#include <iostream>
extern const int Z;
a.cpp
#include <iostream>
#include "b.h"
#include "c.h"
#include "Number.h"
using namespace std;
int main() {
const int Z = 5;
b Objeto1;
c Objeto2;
double H[Z][Z];
Objeto1.Algo(H);
Objeto2.Imprimir(H);
return 0;
}
b.h
#include <iostream>
#include "Number.h"
class b {
public:
void Algo(double[Z][Z]);
};
b.cpp
#include <iostream>
#include "b.h"
#include "Number.h"
using namespace std;
void b::Algo(double H[Z][Z]) {
for(int a = 0; a < Z; a++) {
for(int b = 0; b < Z; b++) {
H[a][b] = Z;
cout << H[a][b] << endl;
}
}
}
c.h
#include <iostream>
#include "Number.h"
class c {
public:
void Imprimir(double H[Z][Z]);
};
c.cpp
#include <iostream>
#include "c.h"
#include "Number.h"
using namespace std;
void c::Imprimir(double V[Z][Z]) {
cout << "dfs" << endl;
}
I know that the code does not make any sense, but I am just trying to understand how I could have a constant for all the files. I really appreciate your help.
Use of
extern const int Z;
is perfectly fine. However, you can't use Z to define an array. Hence, use of Z in the following line, and similar other lines, is incorrect.
class b{
public:
void Algo(double[Z][Z]);
};
The size of arrays must be known at compiler time. With the extern declaration you have provided, that is not true.
The use of extern const is justified only when you wish to define the value at run time and expect the value to not change until the program ends.
If you simply wish to use it as a token for defining arrays, remove the extern and set its value also. Use:
const int Z = 5;

C++: Why do these functions use different copies of the vector?

I have the problem of class functions making changes on different copies of a vector rather than the one saved in an instance of the corresponding object.
Description of the Main function:
This is the main function. It first creates an object Menno of class Mats, which is initialized with its constructor and has a private vector of type int named F full of values -1. It then is used to create an object of class Calculator named Calli. The object Menno is saved in a private object variable of type Mats named Matrices in Calli. Finally, Matrices is returned by the getMatrices() function of Calli and printF() is carried out on this object variable, which changes values in F and is supposed to change F for all time.
Problem:
As can be seen after executing the program, the changes made by printF() and setf() do not get saved in the object variable Matrices. This leads me to think that the initialization of F in the constructor works well, but the functions then use other copies of this vector rather than the saved one.
Background:
As a Java Coder, I was advised to use pointers for most cases, but I still can't understand why this code doesn't work as intended. I recently investigated C++ as a programming language, went through thenewbostons video guide and printed out syntax lists but they don't help me here. Any explanation is appreciated!
// main function
#include "Calculator.h"
#include "Mats.h"
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int N = 4;
Mats Menno(N);
Calculator Calli(Menno);
Calli.getMatrices().printF();
Calli.getMatrices().setf(2,1);
Calli.getMatrices().printF();
}
// Calculator header
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include "Mats.h"
#include <vector>
class Calculator
{
public:
Calculator(Mats M);
Mats getMatrices();
protected:
private:
Mats Matrices;
};
#endif // CALCULATOR_H
// Calculator cpp
#include "Calculator.h"
#include "Mats.h"
#include <iostream>
#include <vector>
using namespace std;
Calculator::Calculator(Mats M)
: Matrices(M)
{
}
Mats Calculator::getMatrices(){
return Matrices;
}
// Mats header
#ifndef MATS_H
#define MATS_H
#include "Calculator.h"
#include <vector>
class Mats
{
public:
Mats(int N);
int getf(int i);
void setf(int i, int fh);
std::vector<int> getF();
void printF();
protected:
private:
std::vector<int> F;
};
#endif // MATS_H
// Mats cpp
#include "Calculator.h"
#include "Mats.h"
#include <iostream>
#include <vector>
using namespace std;
Mats::Mats(int N)
{
std::vector<int> Fh;
F = Fh;
F.resize(N);
for (int i = 0;i<N;i++){
F[i] = -1;
}
}
int Mats::getf(int i){
return F[i];
}
void Mats::setf(int i, int fh){
F[i] = fh;
}
std::vector<int> Mats::getF(){
return F;
}
void Mats::printF(){
F[1] = 300;
cout << "F: " << endl;
for (int i = 0; i<F.size(); i++) {
cout << F[i] << " ";
}
cout << endl;
F[1] = 200;
}
Because
Mats getMatrices();
returns a copy of the class member. Change it to return it by reference:
Mats &getMatrices();
Note that returning a class member by reference has certain ramifications that you need to understand. You will find all the details in your favorite C++ book.
What happened here is that your self-described background in Java is getting in the way. C++ classes work fundamentally different than Java's classes. You need to forget everything you know about classes, as you know them in Java, and focus on learning how C++ classes work, from the basics.

How do I declare a const in a header?

I want to test defining a const in a header and use it in functions, then call it. However I get the error, I added include guards which doesn't help. Error is: LNK1169: One or more defined multiply symbols found. How can i do it in a nother way? Is declaring const in .h and defining this const in .cpp and then including this .cpp in all other .cpps the only solution?
Header
#ifndef STORY
#define STORY
const int x = 4;
#endif
.cpp
#include <iostream>
#include "8-04.h"
void func1()
{
int w = x;
std::cout << "func1 " << w << std::endl;
}
.cpp
#include <iostream>
#include "8-04.h"
void func2()
{
int z = x;
std::cout << "func2 " << z << std::endl;
}
main
#include <iostream>
#include "8-04.h"
#include "8-04first.cpp"
#include "8-04second.cpp"
using namespace std;
int main()
{
func1();
func2();
}
The problem is that each .cpp includes the .h. This means that each .o contains a const int x. When the linker links these together, you get multiple definitions.
The solution is to modify the .h
#ifndef STORY
#define STORY
extern const int x; //Do not initialise
#endif
and in a single .cpp:
const int x=4
Edit:
I didnt even see the #include <file.cpp> business. Don't do that. Its horrible.
This should be like :
header.h:
#ifndef STORY
#define STORY
const int x = 4;
void func1();
void func2();
#endif
fun1.cpp
#include <iostream>
#include "header.h"
void func1()
{
int w = x;
std::cout << "func1 " << w << std::endl;
}
fun2.cpp
#include <iostream>
#include "header.h"
void func2()
{
int z = x;
std::cout << "func2 " << z << std::endl;
}
main.cpp
#include <iostream>
#include "header.h"
using namespace std;
int main()
{
func1();
func2();
}
You can not include ".cpp"
It can be done such as :
header.h:
#ifndef STORY
#define STORY
const int x = 4;
void func1();
void func2();
#endif
fun1.cpp
#include <iostream>
#include "header.h"
using namespace std;
void func1()
{
int w = x;
cout << "func1 value of w = " << w << "\n";
}
fun2.cpp
#include <iostream>
#include "header.h"
using namespace std;
void func2()
{
int z = x;
cout << "func2 value of z = " << z << "\n";
}
main.cpp
#include <iostream>
#include "header.h"
int main()
{
func1();
func2();
}
".cpp" file cannot be included in main source file.

'Undefined reference to Class::method()'

Recently I've been learning how to create methods within classes so that I only have to write a method once and for each of that class I instantiate I can call the one method and it will work only on the variables of the object that called it, I know how to do this when only using main.cpp and no headers however I am confused on how I should be writing this when I use a class header and cpp.
I have a sample of code similar to what I want to achieve:
#include <iostream>
using namespace::std;
class Object
{
public:
int stuff;
void manageStuff();
Object();
};
void Object::manageStuff()
{
stuff++;
}
Object::Object() : stuff(0) {}
Object object1, object2;
int main() {
for (int i = 0; i < 10; i++)
{
object1.manageStuff();
object2.manageStuff();
cout << object1.stuff << "\n";
cout << object2.stuff << "\n";
}
}
This works fine and allows me to have two instances of Object and a method that works independently for each instance, this is my current project:
main.cpp:
#include <iostream>
#include "Test.h"
using namespace std;
int main()
{
Test test;
for (int i = 0; i < 10; i++)
{
test.count(); // Here's my error "undefined reference to Test::count"
}
return 0;
}
Test.cpp
#include <iostream>
#include "Test.h"
using namespace std;
Test::Test()
{
//ctor
}
Test::~Test()
{
//dtor
}
Test.h
#include <iostream>
#ifndef TEST_H
#define TEST_H
class Test
{
public:
Test();
virtual ~Test();
void count();
int counter();
};
#endif // TEST_H
and finally TestFunctions.h
#include <iostream>
#include "Test.h"
#ifndef TESTFUNCTIONS_H_INCLUDED
#define TESTFUNCTIONS_H_INCLUDED
void Test::count()
{
Test::counter++;
std::cout << Test::counter;
}
#endif // TESTFUNCTIONS_H_INCLUDED
I'm sure that there will be something that's very obviously wrong to a more seasoned programmer and I'm about to look a bit thick but any help would be greatly appreciated
Thanks!
I would suggest getting rid of TestFunctions.h, and adding the implementation of Test::count() to Test.cpp. Currently, the TestFunctions.h header is not included anywhere, so you have no access to the definition from main.
You defined (i.e. implemented) Test::count() in a header file (TestFunctions.h), but you never included it anywhere so the code there is not compiled.
You should change it to be in a .cpp file, compile it and link it with the other source files. There's no reason why not to place it in Test.cpp.
Rename TestFunctions.h into TestFunctions.cpp, make it compiled same way as main.cpp and linked.
Alternatively, include TestFunctions.h somewhere, e.g. main.cpp

operator declaration within namespace in a header?

Please excuse me but I didn't know to give a name to the title in a short way.
Why do I need to declare an overloaded operator inside the header to make it work in this example:
HEAD.H
#pragma once
namespace test {
class A {
public:
A() : x(0) {}
int x;
};
A& operator++(A& obj); //this is my question
}
HEAD.CPP
#include "head.h"
namespace test {
A& operator++(A& obj) {
++obj.x;
return obj;
}
}
MAIN.CPP
#include <iostream>
#include "head.h"
using namespace std;
using namespace test;
int main() {
A object;
++object; //this won't work if we delete declaration in a header
return 0;
}
operator++ is defined and declared in a namespace inside "head.cpp" so why do I need to declare it one more time in a header?
Thank you.
The CPP files are compiled independently of each other, and they only see the header files they've included (which are in fact textually added to the source code of the CPP before compilation). As such you'll use the header file to inform the compiler that a function exists with that signature (be it an operator overload).
Then the output from your CPP files is put together by the linker, which is when you'd find out if for instance you had declared a function in a header file but never taken the trouble to implement it.
Simple example with namespaces:
#include <iostream>
namespace test{
int f() { return 42; }
int g() { return -1; }
}
namespace other{
int f() { return 1024; }
}
using namespace other;
int main(){
//error: 'g' was not declared in this scope
//std::cout << g() << std::endl;
std::cout << test::f() << std::endl; //42
std::cout << f() << std::endl; //1024
return 0;
}