Conditional compilation on C++ class member methods - c++

Could you please explain to me why this code using conditional compilation does not compile?
// Example program
#include <iostream>
#include <string>
class Foo{
public:
#ifdef NUMBER
int number(){
return 0;
}
#endif
int number1(){
return 1;
}
};
int main()
{
#ifndef NUMBER
#define NUMBER
Foo foo;
std::cout << foo.number();
#endif
std::cout << foo.number1();
return 0;
}
It shows compilation error:
In function 'int main()':
22:26: error: 'class Foo' has no member named 'number'

As commented, the preprocessor only goes forward.
Here are the lines of your code where NUMBER is not defined:
// Example program
#include <iostream>
#include <string>
class Foo{
public:
#ifdef NUMBER
int number(){
return 0;
}
#endif
int number1(){
return 1;
}
};
int main()
{
#ifndef NUMBER
Here are the lines of your code where NUMBER is defined:
#define NUMBER
Foo foo;
std::cout << foo.number();
#endif
std::cout << foo.number1();
return 0;
}
NUMBER is only defined once you #define NUMBER.
In your code, there is no Foo::number().

Related

"multiple definition of" while variable is not defined anywhere else in the scope

I have these three source files:
test.h
#ifndef __TESTH
#define __TESTH
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
typedef struct {
uint8_t value;
} my_struct;
EXTERNC void initialise();
EXTERNC void load(my_struct**);
#endif
test.cpp:
#include <cstdint>
#include "test.h"
my_struct test;
void initialise() {
test.value = 200;
}
void load(my_struct** struct_ptr) {
*struct_ptr = &test;
}
main.cpp:
#include <cstdint>
#include <iostream>
#include "test.h"
my_struct *test;
int main() {
initialise();
load(&test);
while (true) {
std::cout << test->value << std::endl;
}
}
When I compile it, the linker gives me an error telling me that test has been defined multiple times (first defined in test.cpp).
Why? To me it seems like it doesn't leave the scope of test.cpp.
And when I remove the definition of test in main.cpp, it gives me an undefined error!
Thank you for taking the time out of your day to help me.
I think you would need to scope test.cpp's test variable to that file only, assuming your test pointer in main.cpp is different than test in test.cpp
namespace {
my_struct test;
}
See here

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++ how to correctly reference a class attribute's value

I don't know exactly why this is happening but it seems that the code is "losing" the value of an attribute. I got a class defined as (in Foo.h):
#ifndef FOO_H
#define FOO_H
using namespace std;
#include <string>
class Foo{
public:
Foo(short int id);
void Foo::DoSomething(std::string someMsg);
private:
short int id;
};
#endif /* FOO_H */
in the class implementation (Foo.cpp):
#include "Foo.h"
#include <iostream>
Foo::Foo(short int id) {
this->id = id;
cout << "value now: " << this->id << "\n"; // I print to be sure it was set correctly and it prints the right value
}
void Foo::DoSomething(std::string someMsg) {
cout << "Foo number: " << std::to_string(this->id) << someMsg;
// when it runs this code called by another class, it always prints 0 to this->id for all objects instantiated
}
Then, I got another class, Bar. In Bar.h I have:
#ifndef BAR_H
#define BAR_H
#include <iostream>
using namespace std;
#include <list>
#include "Foo.h"
class Bar {
public:
Bar();
void setValor(std::string valor);
void notifyAllFoos();
void Bar::registerFoo(Foo *h);
private:
std::list<Foo> foos;
};
#endif /* BAR_H */
In Bar.cpp I have:
#include "Bar.h"
void Bar::setValor(std::string valor){
// do more stuff
this->notifyAllFoos();
}
void Bar::registerFoo(Foo *h){
this->foos.push_back(*h);
}
void Bar::notifyAllFoos(){
for(std::list<Foo>::iterator it=this->foos.begin() ; it!=this->foos.end() ; it++){
it->DoSomething("myMsg");
}
}
Finally, in main.cpp:
#include <cstdlib>
#include "Bar.h"
#include "Foo.h"
using namespace std;
int main(int argc, char** argv) {
Bar *b = new Bar();
b->registerFoo(new Foo(1));
b->registerFoo(new Foo(2));
b->registerFoo(new Foo(3));
b->setValor("Value");
delete b;
return 0;
}
Basically, Bar must notify all Foos of it's list that an update of an Value occured and print a Msg. To identify each Foo I put this id but it keeps printing 0 for all.
Why is this happening? It must be something very simple I guess but I'm not used to c++. Thanks in advance.
That:
std::list<Foo> foos;
will store copies of objects from class Foo.
You need to store pointers, like this:
std::list<Foo*> foos;
PS: Never forget to delete for every new, when you are done.
I did take your code and put it into one file, added includes and using at the top and commented out declaration of Bar constructor.
#include <string>
#include <iostream>
using namespace std;
class Foo{
public:
Foo(short int id);
void Foo::DoSomething(std::string someMsg);
private:
short int id;
};
Foo::Foo(short int id) {
this->id = id;
cout << "value now: " << this->id << "\n"; // I print to be sure it was set correctly and it prints the right value
}
void Foo::DoSomething(std::string someMsg) {
cout << "Foo number: " << std::to_string(this->id) << someMsg;
// when it runs this code called by another class, it always prints 0 to this->id for all objects instantiated
}
#include <list>
class Bar {
public:
//Bar();
void setValor(std::string valor);
void notifyAllFoos();
void Bar::registerFoo(Foo *h);
private:
std::list<Foo> foos;
};
void Bar::setValor(std::string valor){
// do more stuff
this->notifyAllFoos();
}
void Bar::registerFoo(Foo *h){
this->foos.push_back(*h);
}
void Bar::notifyAllFoos(){
for(std::list<Foo>::iterator it=this->foos.begin() ; it!=this->foos.end() ; it++){
it->DoSomething("myMsg");
}
}
int main () {
Bar *b = new Bar();
b->registerFoo(new Foo(1));
b->registerFoo(new Foo(2));
b->registerFoo(new Foo(3));
b->setValor("Value");
}
It gives me following output
value now: 1
value now: 2
value now: 3
Foo number: 1myMsgFoo number: 2myMsgFoo number: 3myMsg
Is it what you are looking for?

Compile under Ubuntu with different header type

I have 3 files namely "main.cpp", "testclass.cpp" and "testclass.h". I compile the files by calling:
g++ testclass.cpp main.cpp
main.cpp
#include <iostream>
#include "testclass.hpp"
int main()
{
testclass foo(56);
std::cout << "Object in cpp\t" << numberobject.getNumber() << "\n";
return 0;
}
testclass header
#ifndef TESTCLASS_H
#define TESTCLASS_H
class testclass
{
private:
int number;
public:
testclass();
testclass(int);
int getNumber();
};
#endif //TESTCLASS_H
testclass.cpp
#include "testclass.hpp"
testclass::testclass()
{
}
testclass::testclass(int number)
{
this->number = number;
}
int testclass::getNumber()
{
return number;
}
There will be a compile error
testclass.cpp:7:1: error: prototype for ‘testclass::testclass(int)’ does not match any in class ‘testclass’
testclass::testclass(int number)
^
testclass.h:4:7: error: candidates are: testclass::testclass(const testclass&)
class testclass
^
testclass.cpp:3:1: error: testclass::testclass()
testclass::testclass()
^
However, if I change the "testclass.h" to "testclass.hpp" and also change all #include statment from #include "testclass.h" to #include "testclass.hpp", it works well.
Why I can't compile the .h file? And is there anyway to compile with .h file?
Finally, I found that there is a strange 'testobject.h.gch" file under the same directory. It works fine after I remove it.

Issue with circular dependency even after separating definitions [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 7 years ago.
Please see my previous post here:
Undefined type error even with forward declaration
I moved the definitions to cpp files and I still face the issue. Any ideas why? My files look like this:
Header1.hpp
#ifndef HEADER1_HPP
#define HEADER1_HPP
namespace sample_ns
{
class sample_class{
public:
static int getNumber();
static void print();
};
}
#endif
Header2.hpp
#ifndef HEADER2_HPP
#define HEADER2_HPP
namespace sample_ns
{
class sample_class2{
public:
sample_class2();
int getNumber2();
};
}
#endif
Source1.cpp
#include "Header1.hpp"
#include "Header2.hpp"
#include "stdafx.h"
#include <iostream>
namespace sample_ns
{
int sample_class::getNumber()
{
sample_class2 obj;
return obj.getNumber2();
}
void sample_class::print()
{
std::cout << "Print utility function" << std::endl;
}
}
Source2.cpp
#include "Header2.hpp"
#include "Header1.hpp"
#include "stdafx.h"
#include <iostream>
namespace sample_ns
{
sample_class2::sample_class2()
{
sample_class::print();
}
int sample_class2::getNumber2()
{
sample_class::print();
return 5;
}
}
In my main I call it as:
std::cout << sample_ns::sample_class::getNumber() << std::endl;
I get 'sample_class2' : undeclared identifier. I tried adding class sample_class2; but that still gives me error
EDIT:
my main file:
#include "stdafx.h"
#include <iostream>
#include "Header1.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "hello" << std::endl;
std::cout << sample_ns::sample_class::getNumber() << std::endl;
return 0;
}
The best practice for declaring classes and namespaces in header and cpp files is using structure likes below:
Header1.hpp
#ifndef HEADER1_HPP
#define HEADER1_HPP
#include "Header2.hpp"
#include <iostream>
namespace sample_ns
{
class sample_class{
public:
static int getNumber();
static void print();
};
}
#endif
Source1.cpp
#include "Header1.hpp"
namespace sample_ns
{
int sample_class::getNumber()
{
sample_class2 obj;
return obj.getNumber2();
}
void sample_class::print()
{
std::cout << "Print utility function" << std::endl;
}
}
So by including in header files and using ifndef you become sure that circular dependencies will not occure.