C++ - Getting and setting member variable within same method? - c++

I have a class that derives from a base class that contains its own member variable. In order to keep everything in the classes encapsulated, I'm trying to figure out a clean approach to setting this member variable at the same time retrieving it in the same method. Here is what the method looks like (this is pseudo code and probably won't compile):
class Base
{
virtual void MyVirtualMethod(double &output1, Object &output2)
{
// do base class stuff (does not set output1 because it does not need to)...
output2 = whatever;
}
}
class Derived
{
public:
virtual void MyVirtualMethod(double &output1, Object &output2)
{
// do derived class stuff...
m_DerivedMember = whatever;
// do more stuff...
output1 = m_DerivedMember;
output2 = whatever2;
}
private:
double m_DerivedMember;
}
Calling code #1
std::vector<DataPack> dataPack;
for each Base pointer...
{
double output1(100); // some default value
Object output2;
base->MyVirtualMethod(output1, output2);
dataPack.push_back(DataPack(output1, output2));
}
Calling code #2
double output1(100); // some default value
Object output2;
base->MyVirtualMethod(output1, output2);
// do more stuff but does not actually use output1, just output2...
While this works, it just doesn't seem clean to me. I guess the bigger question I'm asking myself is whether it's a good idea to use the same method as a getter and a setter at the same time? Thanks!

Although I don't recommend this, you can return a reference to your member, which will allow you both get/set operations. This is how std::vector works by overloading operator[]. Something like:
#include <iostream>
using namespace std;
class Foo
{
int m_;
public:
Foo(int m): m_(m){}
int& get_set()
{
return m_;
}
const int& get_set() const // for const-access
{
return m_;
}
};
int main()
{
Foo foo(10);
cout << foo.get_set() << endl;
foo.get_set() = 20;
cout << foo.get_set() << endl;
// that's why we need the `const` overload of `Foo::get_set`
const Foo cfoo(100);
cout << cfoo.get_set() << endl;
}

To answer your question, separate getters and setters are at the core of encapsulation. While it may save you an extra function call, it's much cleaner and safer to have separate functions for getting and setting. Here's some tweaked code to understand better
class Derived : public Base
{
public:
virtual void MyVirtualMethod(double &output1, Object &output2)
{
// do derived class stuff...
m_DerivedMember = whatever;
// do more stuff...
output1 = m_DerivedMember;
output2 = whatever2;
}
/*
The setter
*/
void setDerivedMember(double m){
m_DerivedMember = m;
}
/*
the getter
*/
double getDerivedMember(){
return m_DerivedMember;
}
private:
double m_DerivedMember;
}
And we could invoke these functions like:
Derived d(1.5, string("I'm a string"));
d.setDerivedMember(5.00);
cout <<"Derived Member Value: " d.getDerivedMember()<<endl;
It would output:
Derived Member Value: 5.00
Hope that makes sense!

Related

How to queue up methods to run until a limit is reached

So I have a bunch of objects (subclasses of a parent class) with various functions each having different names, I might not have the resources to run all of the functions for each object so I want to have them in a priority list to run over time.
The code bellow is I believe forbidden by c++.
I get "C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function"
class A;
class Token;
list<Token> tokenList;
class Token{
public:
A* a; //Could be A or a child of A
int* function;
};
class A {
public:
A() {
Token token = Token();
token.a = this;
token.function = &A::hello;
tokenList.push_back(token);
}
int hello(){
cout << "hello" << endl;
return 0;
}
};
The code bellow should work but doesn't look elegant and also doesn't support subclasses having multiple functions they could pass to the list, is there a better way to do this I am missing?
class A;
list<A*> aList;
class A {
public:
virtual int funct();
};
class B : public A{
public:
virtual int funct(){
hello();
return 0;
}
int hello(){
cout << "hello" << endl;
return 0;
}
};
int main(){
//remove objects from list and run their functions in a loop until list is empty or max number of functions were run
Thanks Ted
Solution: Using the first example as mentioned I changed int* function; to int (A::*function)();. Then I can run the function with something like this
A tmp = A();
Token token = *tokenList.begin();
A *a = token.a;
(a->*token.function)();
}
The problem is that in your code int* function; is a pointer to an integer and not a pointer to a function.
If you would define it as int (*function)(); you could easily do what you want. But it would still not work with member functions.
So you need to define it as a pointer to a member function: int (A::*function)();
Here an example to make it work:
class Token{
public:
A* a; //Could be A or a child of A
int (A::*function)(); // pointer to member function with no arg, returning int
};
class A {
public:
A() {
Token token = Token();
token.a = this;
token.function = &A::hello; // Use the address of member function
tokenList.push_back(token);
}
int hello(){
cout << "hello (" << this <<")"<< endl; // added the address of a to see for which object
return 0;
}
};
int main() {
A a;
A b;
for (auto& token : tokenList )
(token.a->*token.function)(); // invoke the member function on the object pointer
}
Online demo
I didn't notice that your tokenList was a global variable. This is rather risky, as everything you create an A (including a temporary one), the tokenList will be updated. When you'll execute it, you'll therefore risk of having dangling pointers, i.e. pointing to an A instance that has already destroyed.

Mocking C++ classes that copy constructors

I'm coming from C# to C++ and when I try to construct tests, copy constructors are making it hard for me to mock the usual way I am accustomed to.
#include <iostream>
using namespace std;
class DB {
public:
virtual int getValue() { return 42; }
DB(const DB& source) { }
DB() { }
};
class DB_Mock: public DB {
public:
virtual int getValue() { return 999; }
};
class A {
public:
A(DB db) {
m_db = db;
}
void doIt() {
cout << "Result:" << m_db.getValue() << endl;
}
private:
DB m_db;
};
int main() {
/* prints 42 as expected */
DB db;
A a(db);
a.doIt();
/* prints 42, expected 999 */
DB_Mock db_mock;
A a2(db_mock);
a2.doIt();
return 0;
}
How do you approach problems like this?
m_db is not a reference or pointer, c++ polymorphism is work with only base class pointer or reference.
A(DB db) {
m_db = db; // m_db just sliced copy of base part of db.
}
Change this to reference like
class A
{
public:
explicit A(DB &db) : m_db(db) // it is initializing not copy
{
}
void doIt()
{
std::cout << "Result:" << m_db.getValue() << std::endl;
}
private:
DB &m_db; // Now m_db is reference
};
Compile and Run Here
Above will work But, You can not change reference value if you want to change use smart pointer[Recommended].
Reference :
Constructors and member initializer lists
Smart pointer
override
See virtual table to understand v_ptr
Edit:
As Pete Becker said be aware of lifetimes, if you pass local variable reference like
A make()
{
DB db;
A a(db);
return a;
}
int main()
{
const A &a = make();
// Wrong db is destroyed (dangling reference).
a.doIt(); // assume doIt(), getValue() are declared as const
return 0;
}
Above code is Wrong (undefined behaviour), So i Recommend to use smart pointer(Heap storage) to avoid this problems.
Thanks.

How can I overload a member function from an instance of a class

I want to make a class where there is a function that is called automatically, to process information stored within this classes instance.
However each instance has different values and possibly a different way for that content to be handeled.
Therefore I need something simmilar to constructor overloading but in a member function. Where every instance can overload the default function or leave it up to the default to handle the input.
How can that be achieved?
Try to Call Functions in Constructor with if else condition
like:
class abc{
abc(){
if username == "member 1"
functioncall();
else
functioncall();
}
}
As far as I see you need some virtual construction emulation. There is a simple C/C++ way to do it.
// Example program
#include <iostream>
#include <string>
struct A;
typedef void (*cb)(A*);
struct A
{
int m_a;
static void foo(A* aref)
{
std::cout << "Print a: " << aref->m_a << "\n";
}
A(cb b=foo)
{
m_a = 100;
b(this);
}
};
int main()
{
A a;
}
It is not very clear, but still does the trick.
By creating a separate class for the variable behavior Callable describes the local data relating to the function, and by being a class, can be derived.
class Callable {
public:
int m_Value;
Callable(int value) : m_Value(value)
{
}
void operator()( int val1, double val2 /* whatever makes sense */ ) {
}
};
Using the function operator void operator()( ...... ) we create a way of making variables of type Callable to look like a function.
class Variable {
public:
Callable myFunction;
Variable(const Callable & howToCall, /* some more stuff */) :
myFunction(howToCall)
{ /* stuff */
}
void aFunction(int data, double value ) {
myFunction( data, value);
}
};
When calling aFunction the current value of myFunction is called.
Finally Variable can change which function it calls, by modifying the value of myFunction....
myFunction = Callable( /* new parameters */ );

C++ inheritance, calling the given classes function instead of its parent?

Really bad title, couldn't think of how to word it, sorry.
So say I had the following code:
class A {
virtual int getSize() {
return 0;
}
}
class B : public A {
int getSize() {
return 32;
}
}
void doStuff(A a) {
std::cout << a.getSize() << std::endl;
}
int main() {
B b;
doStuff(b);
}
It would print out 0, however I want it to print out 32. In other words, I want to pass it the class and it prints out that classes function, so I could create a class C, where the size is 64, and if I pass that C instance to the doStuff function, I want it to print 64.
Is there any way I can do this in C++, would I have to use templates or some fancy C++ feature I don't know about?
A one-byte patch:
void doStuff(A &a) {
std::cout << a.getSize() << std::endl;
}
Your version takes the argument by value, which means that the function makes a copy of b (a copy which is an A) and then calls the copy's getSize(). In this version, the function takes the argument by reference, and calls b's own getSize(), which is B::getSize().
You should use pointers, or even better: smart pointers! That way, the function of the runtime type gets called. It's a basic example of polymorhpism. If you want to avoid pointers, Beta's slicing approach is equally valid.
#include <iostream>
#include <memory>
class A {
virtual int getSize() {
return 0;
}
}
class B : public A {
virtual int getSize() {
return 32;
}
}
void doStuff(std::shared_ptr<A> a) {
std::cout << a->getSize() << std::endl;
}
int main() {
std::shared_ptr<A> b(new B());
doStuff(b); // Will output '32'.
}
This should correctly call the function as implemented by B.
Slicing the object is one approach, and in addition I think you're asking for, I think, a pretty straightforward use of polymorphism in C++. http://www.cplusplus.com/doc/tutorial/polymorphism/
That's almost immediately applicable, just call your class A Shape, and B and C could be Square and Triangle. Your DoStuff function could take a pointer to a Shape, then you can pass it a triangle or a square, and when you deference the Shape in the function, it will call the correct function.
So you'd have (also you need to make the members public, I think):
class A {
public:
virtual int getSize() {
return 0;
}
};
class B : public A {
public:
int getSize() {
return 32;
}
};
void doStuff(A* a) {
std::cout << a->getSize() << std::endl;
}
int main() {
B b;
doStuff(&b);
}

Using pointers in class over multiple functions C++

So I have 2 functions and 1 class.
with 1 function I want to Set value's of the integers stored in a class.
with the other function I want to use these value's again.
I'm using pointers as I thought this would be saved on Memory address's across the whole program.
#include <iostream>
using namespace std;
void Function1();
void Function2();
class TestClass
{
public:
TestClass();
~TestClass();
void SetValue(int localValue)
{
*value = localvalue;
}
int GetValue()const
{
return *value;
}
private:
*value;
};
TestClass::TestClass()
{
value = new int(0);
}
TestClass:
~TestClass()
{
delete value;
}
int main()
{
TestClass *tommy = new TestClass; //this didn't work,
//couldn't use SetValue or Getvalue in functions
Function1();
Function2();
return 0;
}
void Function1()
{
int randomvalue = 2;
TestClass *tommy = new TestClass; //because it didnt work in main, i've put it here
tommy->SetValue(randomvalue);
}
void Function2()
{
TestClass *tommy = new TestClass;
cout << tommy->GetValue();
<< endl; //this gave a error, so I put the above in again
//but this returns 0, so the value isn't changed
}
So, got a solution for me? I didn't got any compile errors, but the value isn't changed, probably because the destructor is called after Function1 has been completed. so how do I do it?
You need to pass your tommy from main() to each of your functions, not create a new one in each time, otherwise you're just losing the new Testclass objects you're creating in your functions, and actually here getting memory leaks because you use new.
Something like:
void Function1(TestClass * tommy) {
int randomvalue =2;
tommy->SetValue(randomvalue);
}
and then in main():
int main() {
TestClass *tommy = new TestClass;
Function1(tommy);
std::cout << tommy->GetValue() << std::endl; // Outputs 2
delete tommy;
return 0;
}
This is an odd use case, though - this would be the kind of thing you'd expect member functions to do. This would be better:
int main() {
TestClass *tommy = new TestClass;
tommy->SetValue(2);
std::cout << tommy->GetValue() << std::endl; // Outputs 2
delete tommy;
return 0;
}
without the need for Function1() and Function2(). Either way, you're going to have to fix:
private:
*value;
in your class, as someone else pointed out.
you are not passing your TestClass to either function so they functions can't see the tommy object you made. Then in each function you create a new local variable that just happens to have the same name as your local variable in main... They are all independent objects
Every time you write new TestClass, you are quite literally creating a new instance of a TestClass object. The new instance is not related to any existing instances in any way, except for being of the same type. To make the single instance of TestClass be "the one" being used by your functions, you need to pass it in as an argument to those functions.
Also -- Don't use pointers unless it is absolutely necessary.
Here's a cleaned up example of your code that accomplishes what it appears you were trying.
class TestClass
{
int value;
public:
TestClass() : value(0)
{}
int GetValue() const { return value; }
void SetValue(int x) { value = x; }
};
// takes a "reference", works somewhat like a pointer but with
// some additional safety guarantees (most likely will not be null)
// This will modify the original passed in TestClass instance.
void SetRandomValue(TestClass& tc)
{
int random = 2; // not really random...
tc.SetValue(random);
}
// take a const reference, similar to above comment, but a const
// reference cannot be modified in this scope
void Print(const TestClass& tc)
{
std::cout << tc.GetValue() << "\n";
}
int main()
{
// create a TestClass instance with automatic storage duration
// no need to use a pointer, or dynamic allocation
TestClass tc;
// Modify the instance (using reference)
SetRandomValue(tc);
// print the instance (using const reference)
Print(tc);
return 0;
}