I hope that I am providing enough information and that I've titled this correctly.
In general, I want to have a class that stores data in my application, and I need several other classes to access the same data. essentially sharing the data between multiple classes.
Short/Concise Code follows:
example.cpp (main application)
// example.cpp : Defines the entry point for the console application.
//
#include "AnotherClass.h"
#include "ObjectClass.h"
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
//Prototype
static void do_example ( );
int main()
{
do_example ( );
}
static void do_example ( ) {
MyObject.a = 5;
cout <<"MyObject.a value set in main application is "<<MyObject.a<<"\n";
AnotherClass m_AnotherClass;
m_AnotherClass.PrintValue();
}
ObjectClass.h
class ObjectClass {
public:
ObjectClass(); // Constructor
int a; // Public variable
} static MyObject;
ObjecClass.cpp
#include "ObjectClass.h"
ObjectClass::ObjectClass() {
a = 0;
}
AnotherClass.h
class AnotherClass {
public:
AnotherClass(); // Constructor
void PrintValue(); // Public function
int value; // Public variable
};
AnotherClass.cpp
#include "AnotherClass.h"
#include "ObjectClass.h"
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
AnotherClass::AnotherClass() {
value = MyObject.a;
}
void AnotherClass::PrintValue() {
cout <<"value in AnotherClass is "<<value<<"\n";
cout <<"it should be the same."<<"\n";
}
But the value is the default value of 0, as if it is a new instance of MyObject. But it should be pulling the value of 5 from the static MyObject.
What am I missing?
A static class instance is a static variable itself. What you expect to happen also makes sense, however, your code does not show how the static instance is handled. In fact, if both MyClassInstances refer to the same object, then you don't even need static declaration.
Also, static variables are defined in cpp files. If you define it in a header, the cpp file (compilation unit) that includes it will define a separate static variable. So, define the static object in the main cpp file and use extern MyStaticClass in the header file. The linker will then link the uses to the same variable.
Related
I am trying to mock global function using https://github.com/apriorit/gmock-global library.
Note: this description contains example of the real scenario not the exact real scenario. Also I am not allowed to make any changes to global.hpp.
My example dir structure looks like below
--src
------global.hpp
------classA.hpp
------classB.hpp
------main.cpp
--ut
------classATests.cpp
------classBTests.cpp
------main.cpp
The ut/main.cpp tests testcases in classATests.cpp and classBTests.cpp.
global.hpp contains a global function
int giveIndex()
{
return 1;
}
classA.hpp calls giveIndex() global function
#include "global.hpp"
class A
{
public:
int checkIndex() { return giveIndex(); };
}
classB.hpp calls giveIndex() global function
#include "global.hpp"
class B
{
public:
int checkIndex() { return giveIndex(); };
}
classATests.cpp contains
#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <gmock-global/gmock-global.h>
#include "src/classA.hpp"
MOCK_GLOBAL_FUNC0(giveIndex, int(void));
using namespace ::testing
struct classATests : public ::testing::Test
{
void Setup() override
{
sut_ = std::make_shared<A>();
}
std::shared_ptr<A> sut_;
};
TEST_F(classATests , checkIndex)
{
EXPECT_GLOBAL_CALL(giveIndex, giveIndex()).WillOnce(Return(1));
sut_->checkIndex();
}
classBTests.cpp contains
#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <gmock-global/gmock-global.h>
#include "src/classB.hpp"
MOCK_GLOBAL_FUNC0(giveIndex, int(void));
using namespace ::testing
struct classBTests : public ::testing::Test
{
void Setup() override
{
sut_ = std::make_shared<B>();
}
std::shared_ptr<B> sut_;
};
TEST_F(classBTests , checkIndex)
{
EXPECT_GLOBAL_CALL(giveIndex, giveIndex()).WillOnce(Return(1));
sut_->checkIndex();
}
The issue now is when i compile and run UT for both classATests.cpp and classBTests.cpp i get errors saying
... multiple definition of 'giveIndex' ;
and
... multiple definitions of gmock_globalmock_giveIndex_instance
Is there any way to avoid this issue ? classA tests and classB tests need to be in 2 different files like it is now.
Functions defined in header files should be defined inline
inline int giveIndex()
{
return 1;
}
otherwise you will get multiple definition errors if you include the header file more than once.
The alternative would be to only declare the function in your header file
int giveIndex();
and then define it (but not inline) in one of your cpp files.
This is the normal way to organise C++ code. gmock has nothing to do with this.
just started to learn c++.I'm trying new things in c++ on thing i wanted to try is to access a class from another class and change its instances and print its instance on screen.
I would like to know 2 things 1)whats wrong with my code 2)where should i declare class declarations (in main file or class definition file?)
here is the error log -
'object::carrier' uses undefined class 'sub'
'cout': is not a member of 'std'
'cout': undeclared identifier
this is what i came up with-
source.h
#include <iostream>
#include <vector>
#include "stuff.h"
int main()
{
object spoon(3);
spoon.get();
}
stuff.cpp
#pragma once
#include <vector>
class object;
class sub;
class object
{
private:
std::vector <sub> thing;
public:
object(int n);
void get() const;
};
class sub
{
private:
int num;
public:
void set_num(int n);
};
stuff.cpp
#include <vector>
#include "stuff.h"
// methods for object
object::object(int n)
{
sub carrier;
carrier.set_num(n);
}
void object::get() const
{
std::cout << carrier.num;
}
// methods for sub
void sub::set_num(int temp_num)
{
num = temp_num;
}
thanks
In your object class, specifically object::get definitions, you use the variable carrier without it being in scope.
When you declare the variable sub carrier in your constructor, it is only accessible in the same scope, that is, inside the constructor. Once your program leaves the scope, the variable carrier is deallocated (deleted).
You must add the variable sub carrier as a member to your class like so:
class object
{
private:
sub carrier
// other stuff
}
Edit:
I so you edited your question.
You must either replace cout with std::cout because cout is part of the c++ standard library. Alternatively, a less verbose option would be to add using namespace std; at the top of every .cpp file. This basically tells the compiler that you can use the namespace std without explicitly saying it. But don't do it for .h files. It's not a good idea.
Firstly, I am giving the codes. Then I am explaining the problem I am facing.
main.cpp
#include <iostream>
#include "acc.h"
using namespace std;
class mem;
int main()
{
show();
return 0;
}
acc.h
#ifndef ACC_H
#define ACC_H
#include "acc.cpp"
void show();
class mem{
int a;
public:
void showa();
void seta(int A);
};
#endif
acc.cpp
#include <iostream>
using namespace std;
void mem::showa(){cout<<a<<endl;}
void mem::seta(int A){a = A;}
void show()
{
mem m;
m.seta(22);
string ss;
cin>>ss;
cout<<"MY name is "<<ss<<" ";
m.showa();
}
"mem" class I declared in "acc.h" file already and added that "acc.h" into acc.cpp file also. But when I am calling that class from a function. It can't response. Showing "a" and "mem" not declared. How can I perfectly link that class definition and member functions of that class so that calling member functions of that class from another function can't create any problem?
If you remove the #include "acc.cpp" from the acc.h file it should compile without any errors. I tried and it compiles for me. I am using Visual Studio 2010 for the same.
Other than this, few more comments:
You can use #pragma once in you header file instead of #ifndef/#define macros. The former is more cleaner.
You dont need to forward declare class mem before main() as you are already including acc.h.
the show() can be moved to where main() is defined making the acc.h/acc.cppfiles dedicated for the mem class.
A header file should always be named after the class it is holding i.e. mem.h/mem.cpp in your case. This informs which file contains which class even without opening the file.
I'm sort of new to C++, and I've been making my way through a bit in my own project. I ran into an error with this header and .cpp file
// main.cpp
#include <iostream>
#include "Header.h"
int main() {
MyClass::TestFunction(); //'MyClass::TestFunction': illegal call of non-static member function
}
// header.h
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
class MyClass {
public:
void TestFunction() {
std::cout << "Hello World\n"; //Where I beleive the issue is
}
};
#endif
Now I think the issue comes from std::cout not being static and the declaration in main.cpp needs it to be static, but I'm not sure how to make it static so that main.cpp works correctly. If anyone could give me a tip as to how I can make things like this work later on down the road, that would be awesome :)
the issue comes from std::cout not being static and the declaration in main.cpp needs it to be static
You either have to make your function static OR to intanciate an object of your class and hen call its function :
main.cpp
int main() {
MyClass pony;
pony.TestFunction();
}
OR
header.h
class MyClass {
public:
static void TestFunction() {
std::cout << "Hello World\n";
}
};
whenever a member function is written inside a class, it can be called only using object. You have to create a object in main function.
// main.cpp
#include <iostream>
#include "header.h"
int main() {
MyClass myObject;
myObject.TestFunction(); //'MyClass::TestFunction': illegal call of non-static member function }
OR
If you dont want to use object, then make the member function as static.
// header.h
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
class MyClass { public:
void static TestFunction() {
std::cout << "Hello World\n"; //Where I beleive the issue is
} };
#endif
I have my header file in which i have the "selection" as you can see it's public static member .
#ifndef SHAREDDATA_H_
#define SHAREDDATA_H_
#include "cocos2d.h"
#include "GameTrinkets.h"
using namespace std;
class SharedData{
private:
//...
//Instance of the singleton
static SharedData* m_mySingleton;
public:
//Get instance of singleton
static SharedData* sharedGameManager();
static int selection;
};
#endif /* SHAREDDATA_H_ */
Where i try to get access is:
I tried setting the selection trough just the namespace as it seemed the correct way to do it
I tried by going trough the singleton instance but got unlucky
So the code where i try it
#include "GameScene.h"
#include "GameTrinkets.h"
#include "SharedData.h"
#include <time.h>
void GameScene::mainSpriteSelection(int selection){
//1
SharedData::selection=3;
//2
SharedData::sharedGameManager()->selection=selection;
}
The error i get is :
[armeabi] SharedLibrary : libcocos2dcpp.so
jni/../../Classes/GameScene.cpp:41: error: undefined reference to 'SharedData::selection'
In C++, when you declare a variable to be static you have to redefine it in the implementation file before you can use the variable. For example,
//in the header file.
class foo{
public:
static int bar;
};
//in the implementation file
int foo::bar // optional initialisation.
//in the main program
//header files
int main(){
foo::bar = desired_initialisation_value; //no problem
}
The error messages tells you that you need to define static variable selection
define it in GameScene.cpp file
int GameScene::selection = 0;
You have to define the static variable outside your class (in the .cpp) as
int SharedData::selection;
Minimal example:
#include <iostream>
using namespace std;
struct Foo
{
static int member;
};
int Foo::member; // definition here
int main()
{
cout << Foo::member << endl;
}
Otherwise you get a linker error.