I'm new to C++ and I'm having trouble with this. So I'm trying to make classes that can call on each other's fields using a generic subclass.
Basically, I'm trying to make a game where there is a generic type and three types that have strengths/weaknesses against each other. I only really have experience in Java, and the translation to c++ for this kind of thing isn't clicking for me
Generic type splits into three types: type 1, type 2, type 3.
Generic type needs to be concrete
In the generic type there are fields attack, defense, hitpoints
types 1, 2, and 3 all inherit these fields.
I'm trying to make a virtual function in the generic class:
virtual void attack(Generic* g);
Problem is, when I try to make type_1.attack(generic) for example, I want to do g->hitpoints to get generic's hitpoints, but it just doesn't seem to work like that in C++.
Additionally, I know I must be doing something wrong, because type 1, 2 and 3 all include the generic type's header, but if I want to include those 3 headers in main.cpp, it'll give me an error for declaring generic 3 separate times.
How would I go about doing this?
Sorry this is a very specific question and it's a little bit vague. Please let me know if I need to clarify anything
Edit: Here is the basic setup of what I'm talking about
//in generic.h
class Generic {
protected:
int hitpoints;
int strength;
int defense;
public:
virtual void attack(Generic* g);
};
//type1.h
#include 'generic.h'
class Type1 : public Generic {
void attack (Generic* g);
};
//in type1.cpp
void Type1::attack(Generic*g) {
g->hitpoints = strength - g->defense;
}
An object can access its own protected members that are inherited from a base class. But an object cannot access another object's protected members. That is the difference between private vs protected - private members can only be accessed by the class that declares them, but protected members can be accessed by the declaring class and its descendants. Both are still private to outside code, though.
To do what you are attempting, hitpoints needs to be public.
type 1, 2 and 3 all include the generic type's header, but if I want to include those 3 headers in main.cpp, it'll give me an error for declaring generic 3 separate times.'
You need to make sure that the class is declared only once. This is usually done with guards in the .h file:
//generic.h
#ifndef GENERIC_H
#define GENERIC_H
//all declarations go here
#endif /* GENERIC_H */
When you type #include "generic.h", the C++ processor will basically just paste the contents of foo.h. Since you included it thrice (via the includes for classes Type1, Type2 and Type3, that each include generic.h), the class is delcared three times.
You should do something like this:
// generic.h
#pragma once
class Generic {
protected:
int hitpoints_;
int strength_;
int defense_;
void do_damage(Generic* g, int damage) { g->hitpoints_ -= damage; }
public:
virtual void attack(Generic* g) = 0;
int hitpoints() const { return hitpoints_; }
int strength() const { return strength_; }
int defense() const { return defense_; }
};
// type1.cpp
void Type1::attack(Generic* g) {
do_damage(g, strength_ - g->defense());
}
To avoid your second problem (a class defined multiple times), there is something called include guards (they guard you from including the same file several times). It works like this way:
// File: type1.h
// At the very beginning
#ifndef type1_h
#define type1_h
// Here come the rest of your file and, at the end:
#endif
This way, the contents of the file are only included once, because after that type1_h will be defined, so everything will be skipped. This may be the only use of #define that is universally accepted in C++.
As for your first problem, protected means that derived classes can read that member for themselves or objects of their own class, but nobody else. This includes that derived classes cannot read that member for objects belonging to another class, including the base class itself. I'm afraid you'll have to rethink your design.
The best that you can do is just changing the privacy of the protected members or, even better, provide public accessors and keep the data members private. public data members are seldom a good idea in classes (structs are a different thing):
class Generic {
private:
int hitpoints;
int strength;
int defense;
public:
virtual void attack(Generic* g);
void SetHitpoints(int hp) {hitpoints = hp;}
int GetDefense() {return defense;}
};
The meaning of protected for data members is subtly different from what you might expect. When you have a class A with a protected data member d and a class B that inherits from A (with public inheritance), then B's member functions can access d – but only on objects of type B, not on any object of type A. If that seems confusing, a code example will hopefully make it clearer:
class A {
protected:
int d;
};
class B : public A {
void fine(B& b) { b.d = 0; }
void wrong(A& a) { a.d = 0; }
};
int main() { }
As the names indicate, the assignment in functions fine is ok, but you'll get a compiler error for the one in wrong if you try to compile the code. The best way to deal with this is probably to make the data members private and write protected member functions that operate on them, as in abyss.7's answer.
For the double inclusion problem, use either include guards or #pragma once.
Related
I'm developing a class for my AVR cpu.
The class is going to handle all port related operations like Set, Read, etc;
Constructor looks like:
(...)
public:
Port(volatile uint8_t * DDR, volatile uint8_t * PORT);
(...)
And it is constructed at the beginning of the main():
int main()
{
Port PortA(&DDRA, &PORTA);
(...)
}
Now I want to make sure that nowhere else in the program object with same parameters would be constructed. It is sure that I cannot create array or map to find it out and throw an exception. It must be done at compile time. So basicly I want to force avr-g++ to check if any other Port(the same first parameter OR the same second parameter) exists in current project.
All functions uses pointers / references to Port objects.
How about the following?
The address of the pointers has to be known at compile-time.
template<int *p>
class Tester
{
public:
static Tester& GetInstance()
{
static Tester t;
return t;
}
private:
Tester() {}
};
int i;
int main()
{
Tester<&i>& t = Tester<&i>::GetInstance();
}
If you only want one instance of a class, then why use classes? The whole purpose of classes, is that you can have multiple intances. Just stick to global variables and free functions.
This is not pretty, but it does get the job done. 10 years experience says embedded work tends to be like this at times. :/
I tested this with a simple class under MSVC, you'll have to adapt for your needs, but it does demonstrate the principle.
Declare your class like this in the header:
class t
{
public:
#ifdef ALLOW_CTOR
t(int i);
~t();
#endif
int get();
private:
int m_i;
};
Then in exactly one file add the line:
#define ALLOW_CTOR 1
include the header file, declare your port instances as file scope variables, and then implement all the class methods of your class, ctor, dtor, accessors, etc.
If you do not place ALLOW_CTOR line in other source files, they can still use the accessor methods in your class, but they can't use the constructor. In the absence of the correct constructor, MSVC complains because it tries to use the default copy constructor, but since the parameter lists don't match, it fails. I suspect the compiler you're using will fail in some way, I'm just not sure exactly what the failure will be.
#Neil Kirk
If failure to provide a declaration of a ctor at all for a compilation unit leads to undefined behavior, then there are ways to solve that.
class t
{
#ifdef ALLOW_CTOR
public:
#else
private:
#endif
t(int i);
public:
~t();
int get();
private:
int m_i;
};
marks the ctor as public in one, but private in all other compilation units, leading to a well defined error: the inability to access a private member function.
In VS, when you type "class." you are presented with a list of functions you can call. Having to look through a list of 15-20 functions, half or more of which being members is not nice.
I'm extremely interested in finding a system that will hide private member functions or move them to the end of the list, so the user doesn't have to scroll through a list of locked functions.
I have four design types:
1) Namespace method hiding
2) Class based method hiding
3) pimpl version
4) _ prefix
Here is the code for clarity:
#pragma once
#include <memory>
using namespace std; // ignore the fact this is global here
struct Hide_Test_Data
{
int value;
};
namespace Hide_Test_Private_Member_Ns
{
void private_function(Hide_Test_Data& data) {}
};
class Hide_Test_Methods
{
public:
Hide_Test_Methods() {}
void private_function(Hide_Test_Data& data) {}
};
class Hide_Test_Methods_Alt
{
public:
Hide_Test_Methods_Alt() {}
void private_function() {}
private:
Hide_Test_Data htd_;
};
class Hide_Test
{
public:
Hide_Test() {}
void public_function()
{
_private_function(); // member function prefixed with _
Hide_Test_Private_Member_Ns::private_function(htd_); // namespace version
htm_.private_function(htd_); // subclass version (no private data)
pimpl->private_function(); // pimpl version (with private data)
}
private:
Hide_Test_Data htd_; // class to hold data
Hide_Test_Methods htm_; // class to hold methods
void _private_function() {}; // _ prefixed member function
unique_ptr<Hide_Test_Methods_Alt> pimpl;
};
Note:
The unique_ptr Hide_Test_Methods_Alt version has member data which the standard one doesn't. Both could be implemented in either way.
The _ prefix doesn't hide the member data, but it does move it to the end of the list. This has the advantage of allowing user to see the private functions if they are interested. My main goal is not to hide the private member functions, just to move them out of the way.
Prefixing data with _ 'should' be safe out of global scope according to the standard as long as it is followed with a lowercase letter.
Which of these designs would be more acceptable in general? I imagine I could work with all four of these design types comfortably, but I would rather hear some input on some of the pros and cons I may not have thought of.
Pimpl uses a pointer to ease copying the member data. In the cases where I don't need to copy the member data, is just using a class better or worse?
I have done some research and found a few related threads in this forum:
Hiding private data members? (C++) - this one points out the pimpl idiom (which I added to my examples above).
How to hide private members of a Class? - talks about VS intellisense not hiding private members
Why does Visual Studio's intellisense show private members and functions? - gives an #ifdef solution that I don't really like the idea of.
I think this question is different enough from the others presented to be worthy posting. Thanks as always.
Generally a pimpl pattern is applied when you want to be able to change implementations at link time and as such must be a pointer
Here you don't want the overhead, so you could consider an inner class and an instance of that class as opposed to a pointer:
class fewfunctions
{
class manyfunctions
{
public:
int a1() { return 0; }
int a2() { return 0; }
int a3() { return 0; }
int a4() { return 0; }
// ... many more
};
public:
int b() { return a.a1() + a.a2() + a.a3() +a.a4(); }
private:
manyfunctions a;
};
Only b will show up as a function (a shows up as locked)
What are the disadvantages of the following implementation of the pImpl idiom?
// widget.hpp
// Private implementation forward declaration
class WidgetPrivate;
// Public Interface
class Widget
{
private:
WidgetPrivate* mPrivate;
public:
Widget();
~Widget();
void SetWidth(int width);
};
// widget.cpp
#include <some_library.hpp>
// Private Implementation
class WidgetPrivate
{
private:
friend class Widget;
SomeInternalType mInternalType;
SetWidth(int width)
{
// Do something with some_library functions
}
};
// Public Interface Implementation
Widget::Widget()
{
mPrivate = new WidgetPrivate();
}
Widget::~Widget()
{
delete mPrivate;
}
void Widget::SetWidth(int width)
{
mPrivate->SetWidth(width);
}
I would prefer not to have seperate headers and sources for the private implementation part of the class because the code is essentially of the same class - should they not reside together then?
What alternatives to this version would be better?
First, let's address the question of whether the private variables should reside with the class declaration. The private part of a class declaration is part of the implementation details of that class, rather than the interface exposed by that class. Any outside "user" of that class (whether it is another class, another module, or another program in the case of an API) will care only about the public part of your class, since that is the only thing that it can use.
Putting all the private variables directly into the class in a private section might look like it puts all relevant information in the same place (in the class declaration), but it turns out that not only are private member variables not relevant information, it also creates unnecessary and unwanted dependencies between your class' clients and what amounts to be implementation details.
If, for some reason, you need to add or remove a private member variable, or if you need to change its type (e.g. from float to double), then you modified the header file which represents the public interface to your class, and any user of that class needs to be recompiled. If you were exporting that class in a library, you would also break binary compatibility since, among other things, you probably changed the size of the class (sizeof(Widget) will now return a different value). When using a pImpl, you avoid those artificial dependencies and those compatibility problems by keeping implementation details where they belong, which is out of sight of your clients.
As you have guessed, there is however a tradeoff, which might or might not be important depending on your specific situation. The first tradeoff is that the class will lose some of its const-correctness. Your compiler will let you modify the content of your private structure within a method that is declared const, whereas it would have raised an error if it would have been a private member variable.
struct TestPriv {
int a;
};
class Test {
public:
Test();
~Test();
void foobar() const;
private:
TestPriv *m_d;
int b;
};
Test::Test()
{
m_d = new TestPriv;
b = 0;
}
Test::~Test()
{
delete m_d;
}
void Test::foobar() const
{
m_d -> a = 5; // This is allowed even though the method is const
b = 6; // This will not compile (which is ok)
}
The second tradeoff is one of performance. For most applications, this will not be an issue. However, I have faced applications that would need to manipulate (create and delete) a very large number of small objects very frequently. In those rare extreme cases, the extra processing required to create an allocate an additional structure and to defer assignations will take a toll on your overall performance. Take note however that your average program certainly does not fall in that category, it is simply something that needs to be considered in some cases.
I do the same thing. It works fine for any simple application of the PImpl idiom. There is no strict rule that says that the private class has to be declared in its own header file and then defined in its own cpp file. When it is a private class (or set of functions) that is only relevant to the implementation of one particular cpp file, it makes sense to put that declaration + definition in the same cpp file. They make logical sense together.
What alternatives to this version would be better?
There is an alternative for when you need a more complex private implementation. For example, say you are using an external library which you don't want to expose in your headers (or want to make optional through conditional compilations), but that external library is complicated and requires that you write a bunch of wrapper classes or adaptors, and/or you might want to use that external library in similar way in different parts of your main project's implementation. Then, what you can do is create a separate folder for all that code. In that folder, you create headers and sources as you usually would (roughly 1 header == 1 class) and can use the external library at will (no PImpl'ing of anything). Then, the parts of your main project which need those facilities can simply include and use them only in the cpp files for implementation purposes. This is more or less the basic technique for any large wrappers (e.g., a renderer that wraps either OpenGL or Direct3D calls). In other words, it's PImpl on steroids.
In summary, if it's just for a single-serving use / wrapping of an external dependency, then the technique you showed is basically the way to go, i.e., keep it simple. But if the situation is more complicated, then you can apply the principle of PImpl (compilation firewall) but on a larger proportion (instead of a ext-lib-specific private class in a cpp file, you have a ext-lib-specific folder of source files and headers that you use only privately in the main parts of your library / project).
I think there is no big difference. You can choose more convenient alternative.
But I have some other suggestions:
Usually in PIMPL I place implementation class declaration inside interface class:
class Widget
{
private:
class WidgetPrivate;
...
};
This will prevent using of WidgetPrivate class outside of Widget class. So you dont need to declare Widget as friend of WidgetPrivate. And you can restrict access to implementation details of WidgetPrivate.
I recommend using of smart pointer. Change line:
WidgetPrivate* mPrivate;
to
std::unique_ptr<WidgetPrivate> mPrivate;
Using smart pointers you will not forget to delete member. And in case of exception thrown in constructor already created members will be always deleted.
My varian of PIMPL:
// widget.hpp
// Public Interface
class Widget
{
private:
// Private implementation forward declaration
class WidgetPrivate;
std::unique_ptr<WidgetPrivate> mPrivate;
public:
Widget();
~Widget();
void SetWidth(int width);
};
// widget.cpp
#include <some_library.hpp>
// Private Implementation
class Widget::WidgetPrivate
{
private:
SomeInternalType mInternalType;
public:
SetWidth(int width)
{
// Do something with some_library functions
}
};
// Public Interface Implementation
Widget::Widget()
{
mPrivate.reset(new WidgetPrivate());
}
Widget::~Widget()
{
}
void Widget::SetWidth(int width)
{
mPrivate->SetWidth(width);
}
I'd like to know if there's any way to access a private member of a class from outside the class. I'll explain my problem.
I have a .hpp file which contains the definition of the class along with its private members and public function (which are the only one I'd like to export). In the corrisponding .cpp I have to use some "support" function which need access to the private members of the class defined in the .hpp.
Here's part of my code:
--- .hpp ---
namespace vision {
class CameraAcquisition {
/* MEMBERS */
CvSize size;
CvCapture *device;
CvScalar hsv_min,hsv_min2,hsv_max,hsv_max2;
/* METHODS */
public:
CameraAcquisition();
~CameraAcquisition();
int findBall();
};
}
--- .cpp ---
#include "CameraAcquisition.hpp"
using namespace vision;
IplImage *grabFrame() {
// code here
}
IplImage *convertToHSV(IplImage *origin) {
// code here
}
IplImage *calculateThresholdedImage(IplImage *converted) {
// code here
}
What I need is for these three functions to access the members of the class CameraAcquisition. Is there any way to do it? Any suggestions will be appreciated. Thank you all
EDIT
Sorry, I forgot an important piece of information here. In the source file, findBall() must call those methods. I defined those methods to make the code easier to read. I cannot declare those methods in the class definition because I don't want to export them.
If I declare them in a "private" block everything works fine, but maybe it's not correct to that (I don't see the point in providing an header file with private methods.
If those members are made private and you need access to them, you're doing something wrong, so my suggestion is that you don't.
Now let's get serious - there are some ways - DISCLAIMER: not all are safe or portable or guaranteed to work:
1) Preprocessor abuse
#define class struct
#define private public
#include "CameraAcquisition.h"
#undef class
#undef private
2) Fake class
class MyCameraAcquisition {
public: //<--- public in your class
/* MEMBERS */
CvSize size;
CvCapture *device;
CvScalar hsv_min,hsv_min2,hsv_max,hsv_max2;
/* METHODS */
public:
CameraAcquisition();
~CameraAcquisition();
int findBall();
};
CameraAcquisition prvt;
MyCameraAcquisition publ = (MyCameraAcquisition&) prvt;
3) Template abuse posted by litb - http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html
This one is, actually, and surprisingly, standard-compliant.
You should not want to access private mebers of objects. Consider providing public getter/setter member functions that outside code can use to affect the private member variables
Alternatively, you can make your support function a member of the class, so it has automatic access to the private members.
If you really want to access private members, you can use the friend keyword to declare another class or function as friend of the current class
class A
{
int a; // private
friend class B;
friend void f(A*);
};
Here both class B (i.e. its member functions) and free function f can access A::a
Use getters in your CameraAcquisition class
i.e.
CVSize getSize() { return size; }
CvCapture* getDevice { return device; }
etc...
You could always declare them as friends by adding in the class definition:
friend IplImage * ::grabFrame();
Compiler used is Visual Studio 2015
This method is not recommended but works.
Lets consider following class
class mydata
{
private:
int x;
public:
mydata(int no)
{
x=no;
}
}
Only data members are stored in the class object.
Now I can access the x using following function.
As I know that class mydata has only one variable it must be the int x.
int getx(mydata *d)
{
return ((int*)d)[0];
/*
How did this work?
-> d is pointing to the mydata object.
as I typecasted it to int* it will be considered as int array.
Of that array (which has lenght 1) access the first element.
*/
}
If there was another variable lets say y of type DATATYPE.
Now, to access y we have to calculate the offset of it from the base of object.
Usually data is stored in the same order in which you declare it.
Also, there is struct padding to be considered in case of heterogeneous data types in the class.
I would like to suggest you to read struct padding in depth.
And the we can get y as
myclass *ptr =new myclass();
int offset_y=//whatever offset of y in number of bytes from base of object of perticular class;
char *byte_ptr_y=((char*)ptr)[offset_y];
DATATYPE y=*((DATATYPE*)byte_ptr_y);
A is a base class, B is an inherited class. A takes member function pointers from B bound with boost::bind+boost::function to store and execute from other base class functions later. The A and B classes are in separate include files. I would like to restrict the developer who implements inherited classes from A that the bound member function pointers in the inherited classes are private functions. The environment is C++, gcc 4.x and Linux.
Sample:
------ INCLUDE FILE -----
#include <boost/bind.hpp>
#include <boost/function.hpp>
struct A
{
protected:
void Register(const char* name, boost::function<void()> FuncPtr)
{
// (I am not intended to pass the name argument, but probably somebody
// knows something gcc magic which would use it to solve the problem.)
// I want to ensure that FuncPtr points to a private member
// function. What can be known: "B::CalledFunction" string and FuncPtr.
// If it is not a private member function then drop an error message
// during run-time or during compilation (???).
}
};
------ OTHER INCLUDE FILE -----
...
struct B : public A
{
B() : A()
{
Register("B::CalledFunction", boost::bind(&B::CalledFunction, this));
}
private:
void CalledFunction()
{
}
};
Any kind of macro magic or similar stuff can also be appreciated before/instead of a simple direct call to A::Register().
Rather than expand the comments, I will propose an alternative based on really using inheritance
#include <iostream>
#include <memory>
class A
{
public:
void call_a() { some_func_a(); }
private:
virtual void some_func_a() = 0; // pure virtual
};
class B : public A
{
private:
void some_func_a() { std::cout << "B::some_func_a" << std::endl; }
};
int main(void)
{
std::auto_ptr<A> a(new B);
// a->some_func_a(); // causes compiler error
a->call_a();
}
If you leave out the definition of some_func_a in B, you'll get a compiler error when you try to instantiate B.
Unfortunately, the restriction you ask for is not possible. Access restrictions are only present at compile time, not runtime; the only thing they do is control (based on lexical scope) what identifiers can be referenced.
Since the calling context producing these bound member functions obviously has access to all its member functions, you cannot distinguish between private and public member functions locally - this rules out any macro hacks. Further, member function pointers do not retain access control information (this is why you can call a pointer to a private member function from another class). As such, checking elsewhere is also not possible.
You may be able to implement this as a compiler pass in something like clang, as the information is available there at compile time; however this is not possible with a normal C++ compiler. However, this may be prone to false positives and false negatives, as the situation in which this is an issue is somewhat ill-defined (what if some derived class B really wants a bound public member function, that it'll use elsewhere?)