c++ Vector declared private in class but has a get function - c++

If I have a class lets say like this in a separate .h file
class myclass{
private:
vector<string> data;
public:
vector <string>& getMydata(){
return this->data;
}
};
How do I then in separate .cpp access the data in the private vector?

the.hpp
#include <string>
#include <vector>
class myclass{
private:
std::vector<std::string> data;
public:
// put some data in it when it's default constructed
myclass() : data{"hello", "world"} {}
std::vector<std::string>& getMydata() {
return data;
}
};
main.cpp
#include "the.hpp"
#include <iostream>
int main()
{
myclass instance;
// get reference to the data in the instance
std::vector<std::string>& data_ref = instance.getMydata();
// use the data. data_ref is a reference to exactly the same vector as in "instance"
data_ref.push_back("Someone from the utside was here!");
// check result
std::cout << instance.getMydata()[0] << "\n";
std::cout << instance.getMydata()[1] << "\n";
std::cout << instance.getMydata()[2] << "\n";
}
Output:
hello
world
Someone from the utside was here!

You separate the implementation into a .cpp the same way you do any function:
vector <string>& myClass::getMydata(){
return this->data;
}
The only difference it you'll need to show that you are implementing the one from the class by putting myClass:: in front of your implementation.
The compiler will allow a member function to access private data, even if it is defined outside the class definition.
i understand that. I guess what i mean to say is in main.cpp how would access the data?
Oh, I see. If you want to access it from main(), or some other non-member function, you need to call your getter:
int main() {
myclass foo;
foo.getMydata().push_back("We're modifying the vector from main()!");
}

Related

C++ Pointer function to other class function

I need help with passing a function pointer on C++. I can't linkage one function for a class to other function. I will explain. Anyway I will put a code resume of my program, it is much larger than the code expose here but for more easier I put only the part I need to it works fine.
I have one class (MainSystem) and inside I have an object pointer to the other class (ComCamera). The last class is a SocketServer, and I want when the socket received any data, it sends to the linkage function to MainSystem.
ComCamera is a resource Shared with more class and I need to associate the functions ComCamera::vRecvData to a MainSystem::vRecvData or other function of other class for the call when receive data and send de data to the function class associate.
Can Anyone help to me?
EDDITED - SOLUTION BELOW
main.cpp
#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include <exception>
#include <unistd.h>
using std::string;
class ComCamera {
public:
std::function<void(int, std::string)> vRecvData;
void vLinkRecvFunction(std::function<void(int, std::string)> vCallBack) {
this->vRecvData = vCallBack;
}
void vCallFromCamera() {
this->vRecvData(4, "Example");
};
};
class MainSystem {
private:
ComCamera *xComCamera;
public:
MainSystem(ComCamera *xComCamera) {
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iChannelNumber, std::string sData) {vRecvData(iChannelNumber, sData); });
}
void vRecvData(int iNumber, string sData) {
std::cout << "RECV Data From Camera(" + std::to_string(iNumber) + "): " << sData << std::endl;
};
};
int main(void) {
ComCamera xComCamera;
MainSystem xMainSystem(&xComCamera);
xComCamera.vCallFromCamera();
return 0;
}
Output will be:
MainSystem RECV Data From Camera(4): Example
You can have ComCamera::vRecvData be of type std::function<void(int, std::string)> and then have ComCamera::vLinkRecvFunction() be like this:
void ComCamera::vLinkRecvFunction(std::function<void(int, std::string)> callBack)
{
this->vRecvData = callBack;
}
and have MainSystem constructor be like this:
MainSystem::MainSystem(ComCamera *xComCamera)
{
using namespace std::placeholders;
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iNumber, std::string sData){vRecvData(number, sData);});
}
Still though the original question has way too much code to go through friend.
Here what you want :
#include<iostream>
using std::cout;
class A; //forward declare A
class B{
public:
void (A::*ptr)(int x); //Only declare the pointer because A is not yet defined.
};
class A{
public:
void increase_by(int x){
a+=x;
} // this function will be pointed by B's ptr
int a = 0; // assume some data in a;
B b; // creating B inside of A;
void analyze(int y){
(*this.*(b.ptr))(y);
} // Some function that analyzes the data of A or B; Here this just increments A::a through B's ptr
};
int main(){
A a; // creates A
cout<<a.a<<"\n"; // shows initial value of a
a.b.ptr = &A::increase_by; // defines the ptr that lies inside of b which inturns lies inside a
a.analyze(3); // calls the initialize method
(a.*(a.b.ptr))(3); // directly calls b.ptr to change a.a
cout<<a.a; // shows the value after analyzing
return 0;
}
Output will be :
0
6
I still don't get why would you do something like this. But maybe this is what you wanted as per your comments.
To know more read this wonderful PDF.

Global static variable initialised with a call to static class function in c++

Not sure how correctly formulate the question but here is the problem.
I have a static lib where I have the following class in a.h:
#pragma once
#include <vector>
class A{
public:
void Run() {
data_.push_back(10);
std::cout << "size: " << data_.size() << std::endl;
}
private:
static std::vector<int> data_;
};
a.cpp is as follows:
#include "a.h"
std::vector<int> A::data_;
And I have another class in b.h:
#pragma once
#include <string>
class B
{
public:
static std::string Get();
};
And b.cpp:
#include "b.h"
#include "a.h"
std::string B::Get()
{
static A a;
a.Run();
return "foo";
}
Now my main app which is using the above static lib is as follows:
#include <iostream>
#include "a.h"
#include "b.h"
static std::string var1= B::Get();
int main(int argc, char** argv)
{
A a;
a.Run();
}
Trying to understand why the output is:
size: 1
size: 1
There should be a single instance of each static data member for the entire class, so there should be a single call to A::data_ constructor.
Am I hitting "static initialization order fiasco"? I.e. data_ is not initialised before I use it, but then I should be getting the crash?
And now lets imagine my data_ holds dynamically initialised items (something none POD). How will it be destructed if at the end data_ holds one item, although I've inserted 2?
And that's what actually is happening in my real life code (it sometimes crashes during destruction of data_).
Getting rid of global static ( static std::string var1= B::Get(); ) solves the problem, but I still want to understand the under the hood problem.
The described case can be reproduced in VS2015 (the real life case is reproducible in gcc 6.2 )
Am I hitting "static initialization order fiasco"?
Most likely.
You can remove the problem by making the static data of a class available via a function call. E.g.
class A{
public:
void Run() {
getData().push_back(10);
std::cout << "size: " << getData().size() << std::endl;
}
private:
static std::vector<int>& getData();
};
std::vector<int>& A::getData()
{
static std::vector<int> data;
return data;
}
When you do that, data will be initialized when A::getData() is called the first time. It removes the static initialization order issue completely.

Passing a generic template parameter from a map?

I am coming from c# so please excuse anything I may get wrong in trying to ask this question.
I have created a map that contains a string and a method to handle invoking a method by a string:
//MyClass.h
void SerializeCustomData();
std::unordered_map<std::string, void(MyClass::*)()> functionMap;
MyMethod() {
functionMap["SerializeCustomData"] = &MyClass::SerializeCustomData;
};
My question is; how can I have my map take in a parameter for the method? Either a generic type or a string in c++?
Example:
SerializeCustomData(std::string);
#include <functional>
#include <iostream>
#include <unordered_map>
class MyClass
{
std::unordered_map<std::string, std::function<void(MyClass&, std::string)>> functionMap;
public:
void MyMethod()
{
functionMap.emplace("SerializeCustomData", &MyClass::SerializeCustomData);
}
void CallSerialize()
{
functionMap.at("SerializeCustomData")(*this, "argument");
}
void SerializeCustomData(std::string s)
{
std::cout << "hello: " << s << "\n";
}
};
int main()
{
MyClass c;
c.MyMethod();
c.CallSerialize();
}
Here the function from the map is called with a MyClass& argument and a string. Note that the MyClass isn't bound to the callback, and so we're passing it explicitly.

C++ Initialization of static function pointer array

I want to create a static function pointer array, so I can jump to a certain function regarding a received index. Like an index jumper.
So imagine a class like this:
Class A
{
private:
static void 1stFunction();
static void 2ndFunction();
static void(*functionPointer[20])(void);
};
Then I would like that functionPointer to get the value of the 1stFunction and 2ndFunction, and maybe even more.
So, how do I initialize it?
As far as I know, when a static member is declared, you can use it even before an instance is created. So I though, lets initialize that function pointer, so later I can call it like this
functionPointer[receivedIndex]();
So i tried to initilize it like this, in the same .h file
void (*A::functionPointer[])(void) =
{
A::1stFunction,
A::2ndFunction,
};
But the compiler gives me redifinition, it says it's already created.
So, pretty sure I'm missing something. I don't know though, if it is syntax or simply it is not possible to do it this way.
I know that function pointers to class's member functions are different than normal function pointers... But this is a static function, so I believe it doesn't belong to an instance and therefore it should work with normal function pointers.
Any help would be appreciated.
Thanks
The following would be a working example that probably achieves what you need.
You need C++11 for the initializer list.
It is a good practice to initialize the static member in the cpp file, as you don't want to have a definition of the static member everytime the header is included (this can lead to linking issues).
You can call callf with the desired index and have the corresponding function called, based on the initialization of the function pointer array.
The output of the program would be:
I am 2ndFunction
Header file
class A
{
private:
static void Function1();
static void Function2();
static void(*functionPointer[20])();
public:
static void callf(int index);
};
Implementation
#include <iostream>
#include "ex.h"
void(*A::functionPointer[20])() {
A::Function1,
A::Function2
};
void A::Function1() {
std::cout << "I am 1stFunction" << std::endl;
}
void A::Function2() {
std::cout << "I am 2ndFunction" << std::endl;
}
void A::callf(int index) {
A::functionPointer[index]();
}
int main(int argc, char const *argv[]) {
A::callf(1);
return 0;
}
Here you have a more modern C++ approach (C++14 needed)
I would advise you to explore lambda functions if you are not restricted to C++03.
#include <iostream>
#include <functional>
#include <vector>
class A {
public:
using f_type = std::function<void(void)>;
f_type f1 = []() { std::cout << "f0" << std::endl;};
f_type f2 = []() { std::cout << "f1" << std::endl;};
static void f3() { std::cout << "f3" << std::endl; }
std::vector<f_type> functions{f1, f2, f3};
};
int main() {
A a;
a.functions[0]();
a.functions[1]();
//adding custom lambda
a.functions.emplace_back([](){ std::cout << "custom f" << std::endl;});
a.functions[2]();
return 0;
}
you can add both functions and lambdas to your container.

Different code behavior in multiple files compared to collocated into single file

Code that I place in a single file behaves differently when separated into multiple files. I have a static field in a class (a std::vector) that I am modifying during global object instantiation which I analyze in main.
I suspect this is due to how objects are created in different scopes, but I thought this scenario would result in sharing the same object.
How can I separate this code and get the same result I see when the code is collocated?
UPDATE If I declare the static object in main.cpp the code works. Is this the only way? That feels messy, it's not where I want to declare it.
Here is the code.
utils.h
#pragma once
#include <vector>
#include <iostream>
class Collector
{
public:
static std::vector<int> Ints;
};
class Aggregator
{
public:
Aggregator(int i);
};
main.cpp
#include "utils.h"
// as noted in my updated question, if I declare Ints here, it works
// std::vector<int> Collector::Ints;
// but I want the freedom to declare this in any source
Aggregator inst(1);
int main()
{
std::cout << "size: " << Collector::Ints.size();
std::cin.get();
return 1;
}
utils.cpp
#include "utils.h"
std::vector<int> Collector::Ints;
Aggregator::Aggregator(int i)
{
Collector::Ints.push_back(i);
}
The output is size: 0
And all the same code in one file would look like this:
#include <vector>
#include <iostream>
class Collector
{
public:
static std::vector<int> Ints;
};
class Aggregator
{
public:
Aggregator(int i);
};
#include "utils.h"
std::vector<int> Collector::Ints;
Aggregator::Aggregator(int i)
{
Collector::Ints.push_back(i);
}
Aggregator inst(1);
int main()
{
std::cout << "size: " << Collector::Ints.size();
std::cin.get();
return 1;
}
And this outputs size: 1, as I desire.
One way to avoid this is to use a static function with a static variable in it.
So for example:
class Collector
{
public:
static std::vector<int> & GetInts(){ static std::vector<int> Ints; return Ints; }
};
This way you are guaranteed the static variable is initialized when you use it regardless of which cpp file you're using it in.
I should stress though that this is not a great idea as you'll have issues with threading. Is there a good reason to make this static?