Is there a way to group methods scoped to a specific class, without using the scoping operator :: every time? At risk of arousing contempt in some, I can make a rough analogy to the JavaScript with statement; however, here it is used in the source, and not executed.
A simplified example: imagine a Cheese class, with the weigh, shred, and melt functions declared as follows:
class Cheese {
public:
Cheese();
... // other constructors, copy, etc.
~Cheese();
int weigh();
int shred();
int melt();
}
Typically the functions definitions are as follows:
Cheese::Cheese() { //constructor stuff };
... // other constructors, copy, etc.
Cheese::~Cheese() { //destructor stuff };
int Cheese::weigh() { return weighed; }
int Cheese::shred() { return shredded; }
int Cheese::melt() { return melted; }
Is there a way to say, "Hey compiler, all these definitions are scoped to the Cheese class."
Perhaps like so?
scope::Cheese {
Cheese() { //constructor stuff };
... // other constructors, copy, etc.
~Cheese() { //destructor stuff };
int weigh() { return weighed; }
int shred() { return shredded; }
int melt() { return melted; }
}
or,
Cheese:: {
Cheese() { //constructor stuff };
... // other constructors, copy, etc.
~Cheese() { //destructor stuff };
int weigh() { return weighed; }
int shred() { return shredded; }
int melt() { return melted; }
}
Other than defining the methods in the function definition block itself (which has various potential disadvantages), no, there is not any way to do this.
At least part of the reason for this is to ensure that classes, unlike namespaces, cannot be "re-opened" to have additional members added.
You can
define the methods fully in the class definition, or
except for constructors and destructors, use a typedef short class name for the implementation.
There are also some less practical possibilities, which include source code preprocessing.
Example:
class Cheese
{
public:
Cheese();
//... // other constructors, copy, etc.
~Cheese();
auto weight() -> int;
auto shred() -> int;
auto melt() -> int;
};
using X = Cheese;
Cheese::Cheese() {}
Cheese::~Cheese() {}
auto X::weight() -> int { return 0; }
auto X::shred() -> int { return 0; }
auto X::melt() -> int { return 0; }
auto main() -> int
{
return Cheese().weight();
}
On a personal note I wish more libraries were header only, with the method definitions in the class definitions. The header only approach can't easily deal with module cross-dependencies, where the implementation of X depends on interface of Y and vice versa, and with current 1960's build technology it can cause impractically long build times. But where the latter problem matters it can be and is often addressed by pouring more hardware on the problem, and happily the first problem is a rare one.
Related
I have a bit of a design problem:
I have a class describing a Robot; It can move to different directions, move a camera to different views etc. It looks something like this:
class Robot {
private:
...
public:
void move_right();
void move_left();
void switch_camera()
void raise_camera()
}
I want to add another method which performs a series of events. Thing is, I need able to abort the events midway.
I do want to clarify that the robot is running on a micro controller and not on a standard OS - so I can't really send a signal to the process or anything.
My first idea was to store the event functions in an array and iterate over it:
#typedef void(robo_event *)(void)
robo_event next_event;
robo_event *event_sequence;
Robot() {
this->next_event = nullptr;
}
void perform_event_series() {
for(this->next_event = *event_sequence; this->next_event != nullptr; this->next_event+=sizeof(robo_event)) {
this->next_event();
}
}
void abort_event_series() {
this->next_event = nullptr;
}
Thing is, the c++ standard forbids storing addresses of member functions, so this is starting to get awkward. I can make the functions static, but I do need to use them quite frequently and that would still be awkward. I want to be able to change to event sequence without too much work if changes are yet to come, so I thought that saving those on some sort of array / vector would be the best.
Any help with c++ member function syntax / better ideas on how to approach this problem would be much appreciated.
Thing is, the c++ standard forbids storing addresses of member functions
C++ most certainly allows you to store pointers to member functions (and variables), but the syntax is a bit different to accommodate the this pointer type, virtual functions, inheritance, etc.
class Example
{
public:
double foo(int x) { return x * 1.5; }
};
int main() {
double (Example::* member_function_ptr)(int);
member_function_ptr = &Example::foo;
Example example;
std::cout << (example.*member_function_ptr)(2) << std::endl;
}
If all your functions are for the same class, same return type, same arguments, etc. then you can make a table of them easy enough.
Storing pointers to member functions is perfectly allowable in c++:
#include <vector>
class Robot {
private:
public:
void move_right();
void move_left();
void switch_camera();
void raise_camera();
};
struct Action
{
Action(void (Robot::*what)(void))
: what(what)
{}
void perform(Robot& who) const
{
(who.*what)();
}
void (Robot::*what)(void);
};
bool should_abort();
void perform_actions(Robot& who, std::vector<Action> const& actions)
{
for (auto&& action : actions)
{
if (should_abort()) break;
action.perform(who);
}
}
int main()
{
std::vector<Action> actions {
&Robot::move_right,
&Robot::raise_camera,
&Robot::switch_camera,
&Robot::move_left
};
Robot r;
perform_actions(r, actions);
}
Pointers to functions are of different types to pointers to members.
You need void(Robot::*)(void) not void(*)(void).
class Robot {
private:
typedef void(Robot::*robot_event)(void)
robo_event next_event;
robo_event *event_sequence;
Robot() {
next_event = nullptr;
}
void perform_event_series() {
for(next_event = *event_sequence; next_event != nullptr; ++next_event) {
(this->*next_event)();
}
}
void abort_event_series() {
next_event = nullptr;
}
public:
void move_right();
void move_left();
void switch_camera()
void raise_camera()
}
I have code like this:
class Human
{
protected:
int age;
std::string sex;
public:
virtual void speak() = 0;
};
class Child:public Human
{
public:
void speak(){std::cout << "I am Child\n";}
};
class Man:public Human
{
public:
void speak(){std::cout << "I am Man\n";}
};
class Woman:public Human
{
public:
void speak(){std::cout << "I am Woman\n";}
};
(don't know, std::shared_ptr<Human> maybe?) operator*(std::shared_ptr<Child> &b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man")
{
return (i want b to become std::shared_ptr<Man>)
}
if(b->getAge()>18 && b->getSex()=="Woman")
{
return (here I want b to become std::shared_ptr<Woman>);
}
return;
}
int main(){
auto x = std::make_shared<Child>;
x*19;
}
I know it seems odd, but it's the simplest case i can think of, without having to write down all code i'm struggling with rn. Could someone explain, what type should overload be and how to change shared_ptr type, knowing they derive from same parent?
Objects cannot change type. A Child object will always be a Child object. What you can do is create a new object with the properties you want and return that:
std::shared_ptr<Human> operator*(std::shared_ptr<Human> b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man") {
return std::make_shared<Man>(b->getAge());
} else if(b->getAge()>18 && b->getSex()=="Woman") {
return std::make_shared<Woman>(b->getAge());
} else {
return b;
}
}
int main(){
std::shared_ptr<Human> x = std::make_shared<Child>;
x = x*19;
}
This doesn't seem like a good design though. A Human's status as a child or adult would be better represented as an attribute of the object or by a function that checks if age is greater than 18.
You cannot make the type T<Derived> inherit from T<Base> because C++ templates do not support covariance. To do so would be unsafe for certain types, such as mutable references to containers. (Imagine taking a reference to std::vector<Cat> as std::vector<Animal>& and pushing back a dog!)
(I would make this answer a comment, but I don't have comment abilities.)
Update:
You can write a non-template wrapper that handles heap data:
class Wrapper
{
public:
Wrapper(Base* b) : raw(b) {}
~Wrapper() { delete raw; }
Base& get() { return *base; }
private:
Base* raw;
}
Of course, in your example, you use std::shared_ptr and not std::unique_ptr. You would have to handle reference counting instead of simply deleting the data in the destructor, but the technique of keeping an internal raw pointer still stands.
Update 2:
The above code could be used as is to provide a level of indirection, such that all classes that inherit from the base class may be held in the same type, without writing your own reference counter:
std::shared_ptr<Wrapper>
This solution may be seen as similar to doing std::shared_ptr<Base*>, except that the latter solution would leak memory.
I want to do some conditional checks within a bool member function of a struct. How will my struct object struct1 know the bool member function has returned true, so that integers a & b can be used within the calc member function?
int main() {
vector<Point> pt;
pt.push_back(Point{ 1.5, 4.2 });
pt.push_back(Point{ 2.4, 3.1 });
doSth struct1;
bool tempbool = struct1.memfuncbool(pt); //error starts here!
if (tempbool) {int answer = struct1.calc(1);} //??
std::cout << answer;
return 0;
}
struct Point {
double _x;
double _y;
};
struct doSth {
int a, b; //data members
int calc(const int k) {
return (a + b)*k;
}
bool memfuncbool(const vector<Point> &pts) {
//does stuff...
a = var1; //var1 = 1
b = var2; //var2 = 2
return true;
}
}
There are two approaches: encapsulation for caller safety and pure code discipline. In the later you yourself make sure that the code you write is always aware of the latest result of memfuncbool and when and where a and b are set.
In the first you can add a flag in your struct that you set once memfuncbool is called and check in calc (and handle it appropriately.) In that case you should also make sure that the flag is cleared when initialising your struct - either via constructor or again code discipline (like always zero your structs).
An information hiding approach (C++) in the first sense would look like this:
class DoSth {
int a, b;
bool valid;
public:
DoSth() : valid(false) { }
bool isValid() const { return valid; }
/// returns calc if valid, otherwise 0
int calc(int k) const {
return isValid() ? (a + b) * k : 0;
}
void setSth(...) {
a = ...
b = ...
valid = true;
// instead of returning here the caller can check isValid() anytime
}
};
Your code has many issues that could easily be solved if you didn't try to do more than you know.
1 You're defining both Point and doSth structures AFTER the main function. So the main function has no way to know what your structures do. Normally you would use a header file to contain the declaration and the cpp file to contain the implementation, but since you're doing a small program you can just move the definitions of your structures to be above the main function. Alternatively you can declare your structures above main and implement them below, like this.
// Definition of struct Point
struct Point {
double _x;
double _y;
};
// Definition of struct doSth
struct doSth {
int a, b; //data members
// **Declaration** of doSth methods
int calc(const int k);
bool memfuncbool(const std::vector<Point> &pts);
};
int main() {
...
}
// Definition of calc method
int doSth::calc(const int k) {
...
}
// Definition of memfuncbool method
bool doSth::memfuncbool(const std::vector<Point> &pts) {
...
}
2 In the main function you're using a variable called answer in a scope that doesn't know such variable.
if (tempbool) {
int answer = struct1.calc(1);
}
std::cout << answer; // ERROR: answer is not a known variable
See, you're declaring a variable inside an if condition but using it outside. You have to declare the variable outside as well if you want to use it.
int answer = 0;
if ( tempbool ) {
answer = struct1.calc(1);
}
std::cout << answer << std::endl; // OK
OR
if ( tempbool ) {
int answer = strut1.calc(1);
std::cout << answer << std::endl;
}
else {
std::cout << "Invalid result!" << std::endl;
}
This is a fix to compile what you have done so far. But this is not a solution to your code design question.
3 Code Design
Although I suggested quick fixes to your code your actual problem has to do with how you design your classes and structure your code. I've showed you what you did wrong in your code, but your problem can be solved using a better structured approach.
While writing my answer Beyeler already answered this part for you, so check his answer.
EDIT
In your code you are probably doing
using namespace std;
But you've written both vector< Point > and std::cout. You should not use the using line, to begin with, to avoid name collisions and to help YOU know where this vector is coming from.
However, if you insist on using this line so you don't have to write std:: (and it's OK if you know what you're doing), don't go typing std:: on one thing and then omit it in another. Be consistent, either use it or don't.
I found three errors with your code:
"do" is a c++ keyword. You can't use it to name structs.
The parameter of the "memfuncbool" is missing its type. const& is not a type.
Missing semicolon after struct definition.
Also i supposed that var1, var2 and arg are well defined. If they are not even that is a error.
After correcting these errors maybe you can do something like-
if(tempbool) { /*statements*/ };
I have a class transition and inside, a member function rate. I am asking for a method that would allow me to insert custom designed rates into instants of transition, after those instants have been created, and would be fast at run-time!
I would like to optimize the code for speed. rate does simple computations but is called very frequently and many times by the program. So I guess I should avoid virtual functions... Question: what are the other best methods to achieve this in C++ (templates,boost,...)? Comments about the speed of a particular method would be appreciated. Thanks!
class transition {
public:
transition() : vec() {}
double rate(T_vec::iterator a) { return ...; }
private:
T_vec vec;
};
/* custom rate #1 */
double my_rate_1( T_vec::iterator) {
/* do something */
return ans;
}
/* custom rate #2 */
double my_rate_2( T_vec::iterator) {
/* do something */
return ans;
}
const int N=10;
int main (void) {
vector<transition*> ts(N);
for(int i=0;i!=N;++i) ts[i] = new transition;
/* How to efficiently implement the pseudo code that follows? */
ts[0]->rate = my_rate_1;
ts[1]->rate = my_rate_2;
/* ... */
}
There are at least three ways to implement this.
Option 1 is virtual methods. You can't bind the method after you create the instance, but after the creation you can treat all the derived classes as transition.
class transition {
...
virtual double rate(T_vec::iterator a) = 0;
};
class my_transition_1 : public transition {
...
double rate(T_vec::iterator a) { ... }
};
class my_transition_2 : public transition {
...
double rate(T_vec::iterator a) { ... }
};
Option 2 is callbacks. You can change the method at runtime, after you created the object. It's the most dynamic. It has slightly higher overhead in this case, because there is an extra copy construction of the iterator, and it is harder for the compiler to optimize away the indirect call.
class transition {
public:
....
typedef double (*RateFunction)(T_vec::iterator a);
void set_rate(RateFunction r) { _fun = r; }
double rate(T_vec::iterator a) { return (*_fun)(a); }
private:
RateFunction _fun;
};
double my_rate_1(T_vec::iterator a) {
...
}
...
transition t;
t.set_rate(my_rate_1);
Option 3 is functor templates. You have to specify everything at construction time, but this avoids the indirect call and has the best performance.
template <typename Rate>
class transition {
double rate(T_vec::iterator a) {
return Rate()(a);
}
};
class my_rate_1 {
double operator()(T_vec::iterator a) {
....
}
};
class my_rate_2 {
double operator()(T_vec::iterator a) {
....
}
};
transition<my_rate_1> t1;
transition<my_rate_2> t2;
Option 4 is not extensible, but you avoid the indirect function call and have the opportunity to set the rate after creating the object.
class transition {
public:
enum RateCode {
RATE_1,
RATE_2,
...
}
double rate(T_vec::iterator i) {
switch (_rate_code) {
case RATE_1: {
...
return result;
}
case RATE_2: {
...
return result;
}
default:
assert(false);
}
}
void setRate(RateCode r) { _rate_code = r; }
private:
RateCode _rate_code;
}
If you want to bind to arbitrary functions, check the FastDelegate article. There is also an article of a more portable implementation of the delegate idea.
If you can arrange your code such that the specific instance is known at compile time, this will be faster, assuming the compiler does its job well. The reason why it is faster is that a true delegate implies a call to a function pointer, and that breaks the speculative execution and pipelining in today's CPU's.
You might also want to read up on C++11. In C++11, lambda functions (inline written functions that can be passed around) are an important extension, and I would expect compilers to work hard to optimize them.
Is it possible to get a list of functions in a certain namespace or all functions in a program at runtime?
I have a function pointer map and I need to add commands on my own to it, but I thought: why not create a namespace and let the program do the work at runtime?
something like(pseudocode):
typedef bool (*command)(void);
namespace Commands
{
bool Start(void)
{
return true;
}
bool End(void)
{
return true;
}
};
std::map<std::string,command> CommandMap;
main()
{
for(each function in namespace Commands)
{
CommandMap[std::string(function_name)] = function;
}
CommandMap["Start"]();
CommandMap["End"]();
return 0;
}
instead of
std::map<std::string,command> CommandMap;
main()
{
CommandMap["Start"] = Commands::Start;
CommandMap["End"] = Commands::End;
//list of thousands of other commands......
CommandMap["Start"]();
CommandMap["End"]();
return 0;
}
Is this possible to achieve in C++ or C++11? Or any alternatives to my goal?
No (it has to be 30 characters).
EDIT: This goes along with my comment about how much control you have. You could redefine all of your functions as functors, and have the constructor register itself with some array. Your base class would look like this:
EDIT2: read the comment about all functions having same arguments and return types, makes it a little cleaner.
class myFunctorBaseClass
{
public:
myFunctorClass () : {//register myself, no duplicates}
virtual int operator () (int);//Whatever types you want
};
class myFunctor: public myFunctorBaseClass //Define as many of these as you need
{
public:
int operator() (int y) { return y; } // Define this as whatever you want
}
This obviously would depend on the objects being constucted, but assuming they all were as an initialization step, this would get you what you want.
NOTE: This may be incomplete/not compile. I just kinda wrote this off the top of my head, but it should be close. The reference you want is "functors" if you have questions about how this works.
Consider something like:
class CommandCollection
{
...
void register_command(Command*, string);
map<string, Command*> m_command_map;
}
class Command
{
...
virtual do_command(...) = 0;
}
class EachCommand : public Command
{
EachCommand() { CommandCollection::instance().register_command(this, my_name); }
...
virtual do_command(...);
}
EachCommand each_command_inst;
The Command base class has a virtual to do a command. Each derived type implements the command (you could try overloading the () operator to make them look more like functions).
Each derived Command registers itself with the CommandCollection, so it can be known in a central location. If you want to associate the commands by string (seems good if a user is typing them in), then that would be the key in the map.
As mentioned elsewhere, names (in C and C++, other languages may/do differ on this point) only really exist as part of the source-code. Once compiled, the names cease to have any meaning in C and C++.
One could, however, consider some sort of structure like this:
class CommandBase
{
virtual bool doCommand() = 0;
virtual std::string name() = 0;
virtual ~CommandBase() {}
};
class StartCommand : public CommandBase
{
bool doCommand() { ...; return true }
std::string name() { return "Start"; }
};
void RegisterCommand(CommandBase *cmd)
{
CommandMap[cmd->name] = cmd;
}
...
StartCommand start;
...
void someFunction()
{
RegisterCommand(&start);
}
I'll probably get a downvote for mentioning macros, because these are evil - don't use this if you are a purist that don't like macros.
#define CMD(x) CommandMap[#x] = Command::x
CMD(start);
CMD(end);
There are certainly other variants, and someone who knows templates may well come up with something that does this using templates.