I am new to TBB. I met a problem, I hope you guys can give me some advise.
A class named Fruit:
Fruit.hpp:
class Fruit {
protected :
void A(...);
void B(..);
public :
Fruit();
~ Fruit();
void l1(....);
void l2(...);
};
Fruit.cpp:
custom_TBB (...){
//How to call the method A of Fruit?
}
class Fruit {
...
Fruit::l1(....){
tbb::task_scheduler_init init(numberOfThreads);
parallel_for(tbb::blocked_range<int>(0,End,10000),custom_TBB (...));
}
...
};
Because I need to use parallel method in the function of l1.
I am not sure whether my understanding of TBB is right to not?
I would like to know how can I make this works?
Thank you first.
This is my idea:
1. I tried to declare custom_TBB inside the class Fruit, and implement it here, but failed.
2. I tried to define custom_TBB inside the function of l1, but also failed.
Ideally you should declare that tbb::task_scheduler_init init(numberOfThreads); as soon as you can in your program. I generally have it as pretty much the first thing in the main() function of anything I do using TBB.
Related
Hello guys a have a problem, that i can't access field tablica[i]->help, in generuj function, its saying that this field is not existing in class Task.
How can i achieve it ?
class Task
{
protected:
string contents;
int id_pyt;
int nr_pyt;
};
class Task4Answ : public Task
{
private:
int help;
public:
Task4Answ(string contents1, int id,int nr,int help1)
{
contents=contents1;
id_pyt=id;
nr_pyt=nr;
help=help1;
}
};
class TaskCollection
{
protected:
Task *collection[60];
public:
friend class Generator;
TaskCollection()
{
collection[0] = new Task4Answ("Ile jest por roku w Polsce? \na) 1 \nb) 2 \nc) 3 \nd) 4",1,0);
collection[1] = new Task4Answ("Kto wygral tegoroczny Roland Garros? \na) Federer \nb) Djokovic \nc) Nadal \nd) Thiem",1,1);
class Generator
{
protected:
Task *tablica[10];
TaskCollection T1;
public:
Generator(){}
void Generuj()
{
if(T1.collection[x]->id_pyt==1)
{
tablica[i]=new Task4Answ("0",0,0);
tablica[i]->contents=T1.collection[x]->contents;
tablica[i]->id_pyt=T1.collection[x]->id_pyt;
tablica[i]->nr_pyt=T1.collection[x]->nr_pyt;
tablica[i]->help=T1.collection[x]->help; //here is the problem
}
}
}
Or maybe there is some other solution of the project im doing now.
Thanks for any help.
The problem is in this line:
tablica[i]=new Task4Answ("0",0,0);
Although you have called the Task4Answ constructor, you are also assigning the memory address returned by new to a Task pointer. Effectively, you have casted the Task4Answ pointer to a Task pointer. On the lines that follow, C++ only sees tablica[i] as a reference to a Task pointer. You need to change:
protected:
Task *tablica[10];
TaskCollection T1;
...to this:
protected:
Task4Answ *tablica[10]; // Task was changed to Task4Answ
TaskCollection T1;
That should allow C++ to see tablica as an array of Task4Answ pointers instead of Task pointers.
Edit: it looks like help is also private. You will have to change help to public or add TaskCollection::TaskCollection() as a friend. Otherwise, C++ will not let you get or set help.
Edit: the OP added that tablica[i] might contain instances of other classes that inherit from Task. In that case, you could do something like this:
void Generuj()
{
if(T1.collection[x]->id_pyt==1)
{
Task4Answ* newTask = new Task4Answ("0",0,0);
newTask->contents=T1.collection[x]->contents;
newTask->id_pyt=T1.collection[x]->id_pyt;
newTask->nr_pyt=T1.collection[x]->nr_pyt;
newTask->help=T1.collection[x]->help; // You will still have to change this from being private.
tablica[i] = newTask;
}
}
}
Later on, in order to access help, you will need to implement some sort of way of checking whether tablica[i] is a Task4Answ and not an instance of some other class that inherits from Task, perhaps by implementing a method in Task named IsTask4Answ that returns false in Task but is overridden to return True in Task4Answ. You can then cast the pointer back to Task4Answ with something like the static_cast operator. In other words:
// Add these functions to the class definitions:
virtual bool Task::IsTask4Answ() const {
return false;
}
bool Task4Answ::IsTask4Answ() const override {
return true;
}
// Later, you can do this:
if(tablica[i].IsTask4Answ()){
Task4Answ* t = static_cast<Task4Answ*>(tablica[i]);
t->help; // Again, you'll have to change this from being private.
}
Although I suggest figuring out a different data structure where you do not need to do any casting, this will allow you to access help.
Do note the virtual keyword in the first function above; it allows the function to be dynamically bound, which means that the code will check whether to call Task::IsTask4Answ() or Task4Answ::IsTask4Answ() at runtime instead of at compile time.
I have a problem with typename SnakeGame. I would like to know how to make SnakeGame to global type in class KeyboardEvents. Now a nested class like DirectionKeyboard don't know what the type SnakeGame is, since it only sees see KeyboardEvents<SnakeGame> type. I don't know how to change it :P
Here's the error:
no know conversion for argument 1 from 'KeyboardEvents SnakeGame>&' to 'SnakeGame&'
I would really appreciate help .
keyboardEvents.hpp
#include<SFML/Graphics.hpp>
template <typename SnakeGame>
class KeyboardEvents {
public:
virtual ~KeyboardEvents() = default;
protected:
class DirectionKeyboardEvent{
public:
virtual ~DirectionKeyboardEvent() = default;
virtual void direction(SnakeGame&) = 0; // error no know conversion
};
class GoRight : public DirectionKeyboardEvent {
public:
void direction(SnakeGame& snakeObj) {
snakeObj.snake[0].xCoor+=1;
}
};
class GoRight : public DirectionKeyboardEvent {
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].xCoor += 1;
}
};
class GoLeft : public DirectionKeyboardEvent{
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].xCoor-=1;
}
};
class GoUp:public DirectionKeyboardEvent{
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].yCoor-=1;
}
};
class GoDown : public DirectionKeyboardEvent{
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].yCoor+=1;
}
};
std::map<sf::Keyboard::Key, std::shared_ptr<DirectionKeyboardEvent>> mapOfDirects;
void initializeDirectionMap() {
mapOfDirects[sf::Keyboard::Right] = std::shared_ptr< DirectionKeyboardEvent >(new GoRight);
mapOfDirects[sf::Keyboard::Left] = std::shared_ptr<DirectionKeyboardEvent>(new GoLeft);
mapOfDirects[sf::Keyboard::Up] = std::shared_ptr<DirectionKeyboardEvent>(new GoUp);
mapOfDirects[sf::Keyboard::Down] = std::shared_ptr<DirectionKeyboardEvent>(new GoDown);
}
void chooseMethodFromKeyboardArrows(sf::Keyboard::Key codeFromKeyboard) {
auto iterator = mapOfDirects.find(codeFromKeyboard);
if(iterator!=mapOfDirects.end()){
iterator->second->direction(*this);//left , right,up , down, pause
mainDirection=codeFromKeyboard;
} else {
mapOfDirects[mainDirection]->direction(*this);
}
}
};
Here's the class where I use KeyboardEvents ~ snakeGame.hpp
#include"keyboardEvents.hpp"
class SnakeGame:public Screen, public KeyboardEvents<SnakeGame> {
public:
SnakeGame(int size=16, int width=15, int height=15, int timeDelay=60000)
: Screen(size, width, height), KeyboardEvents<SnakeGame>(), timeDelay(timeDelay) {}
};
In your try to call the DirectionKeyboardEvent::direction inside the KeyboardEvents class.
Even if you put a template parameter that happens to be the child class, there is no means to compiler can know in advance that KeyboardEvents<SnakeGame> will absolutely be extended by the class SnakeGame.
I mean, one could write this code:
KeyboardEvents<SnakeGame> keyboardEvents;
keyboardEvents.chooseMethodFromKeyboardArrows(/* some key */);
In that case, keyboardEvents is not related that much to SnakeGame. In fact there is no SnakeGame instance created at all! The compiler is right, the function chooseMethodFromKeyboardArrows that call direction is wrong to assume that a KeyboardEvents<SnakeGame> is a SnakeGame.
Inheritance work the other way around: a SnakeGame is indeed a KeyboardEvents<SnakeGame>. The other way is false.
I could show you how "to make it work", but a warning is needed here: you are overusing inheritance, and you used it the wrong way in the case of KeyboardEvent. You really should try to rearrange things around, or you'll end up in a real mess.
The solution "make it work"
Since you are using CRTP, you can tell the compiler that KeyboardEvents<SnakeGame> is indeed, in absolutely ALL cases, being extended by SnakeGame. If that's really the case, you can just static_cast your base class to the child class:
if(iterator!=mapOfDirects.end()){
// Notice the presence of the cast here
iterator->second->direction(static_cast<SnakeGame&>(*this));
mainDirection=codeFromKeyboard;
}
The slightly better solution
You can as well using an existing instance of your snake class as parameter.
void chooseMethodFromKeyboardArrows(sf::Keyboard::Key codeFromKeyboard, SakeGame& game){
auto iterator = mapOfDirects.find(codeFromKeyboard);
if(iterator!=mapOfDirects.end()){
iterator->second->direction(game);
mainDirection=codeFromKeyboard;
} else {
mapOfDirects[mainDirection]->direction(game);
}
}
However, the best idea is to not make SnakeGame extending KeyboardEvent, but to contain it in the class instead:
struct SnakeGame : Screen {
KeyboardEvent<SnakeGame> event;
void callEvents() {
event.chooseMethodFromKeyboardArrows(/* some key */, *this);
}
};
Here's an homework for you:
Try to make the class KeyboardEvent not a template. I'm sure you can find a way to pass around your class without the use of themplates, while still accessing directly to your class SnakeGame, without casts or interfaces.
Your design seems a bit overcomplicated. I think the reason this is so is perhaps you were designing it as you went along. Sometimes it helps to sit down and think about these things first, draw boxes and lines on a whiteboard if you have to.
In any case, this isn't a direct answer to your question, it's a suggestion for an alternative based on what I'm guessing you are trying to do.
It seems to me that you're trying to implement some generic keyboard input handler and tie it in to your game. It's possible that I'm entirely wrong about this, but if not, consider something like this instead. First, a generic interface for things that receive keyboard events. It need not be a template, this isn't really a good use-case for templates:
class KeyboardEventHandler {
public:
enum Direction { Left, Right, Up, Down };
virtual ~KeyboardEventHandler () { }
virtual void onDirectionKey (Direction d) = 0;
};
Now your SnakeGame, which handles keyboard events, can inherit that and implement its own SnakeGame-specific logic:
class SnakeGame : public KeyboardEventHandler {
public:
void onDirectionKey (Direction d) {
switch (d) {
case Up: ...
case Down: ...
case Left: ...
case Right: ...
}
}
};
And then whatever bit of code you have that is actually processing keyboard events and driving all of this can just work with a KeyboardEventHandler *, which could be a SnakeGame, or could be anything else you decide to use it for in the future.
That's just one possibility for organization. For example, you could structure it like this instead, breaking out the KeyboardEvent, which could simplify future additions:
class KeyboardEvent {
public:
enum Direction { Left, Right, Up, Down };
Direction getDirection () { ... } // or whatever
};
class KeyboardEventHandler {
public:
virtual ~KeyboardEventHandler () { }
virtual void onEvent (KeyboardEvent &event) = 0;
};
With SnakeGame as:
class SnakeGame : public KeyboardEventHandler {
public:
void onEvent (KeyboardEvent &event) {
...
}
};
You could name that stuff something else besides Direction / onDirectionKey if you want, I picked that from your example but just make it something semantically appropriate that is also convenient (e.g. if you plan on expanding it to include more than just the arrows). But whatever, that's beside the point.
There are also 10 zillion other ways to skin this cat but the important take-home point is: If you're trying to make some generic interface for something, you really can't make it rely on the specific details of what inherits it, otherwise you're defeating the purpose of making it general to begin with. In that case, either it's not a good case for generic bases / inheritance, or you've just botched the design and need to sit back and rethink.
Remember: Your goal isn't to add as many classes and stuff as possible to your code; you're not going for like, an inheritance high score. Your goal is to keep your code clean, readable, maintainable, correct, possibly reusable, and to make your work easier on yourself. These are tools, don't just use them because you have them, instead use them when you need them to make your life easier.
However, all that said, this is still overkill for your specific application, although it is an interesting exercise. To be honest, in your specific case, I'd just chuck all the inheritance and such altogether and do something like:
class SnakeGame {
public:
void handleKeyPress (char c) {
// ... do the right thing here
}
}
And be done with it.
I want to build a somewhat flexible inheritance for different HLSL-Shaders. Sadly my planned route did not work, and i am wondering why. Here is what i am doing:
I have a base-struct and some structs which inherit from it:
struct baseStruct {};
struct childStruct1 : public baseStruct {
int someInt1;
int someInt2;
}
struct childStruct2 : public baseStruct {
float someFloat1;
bool someBool1;
}
And an abstract class with pure virtual functions declared like this:
class BaseClass {
virtual void Function1(baseStruct& structVal) = 0;
virtual void Function2(baseStruct& structVal) = 0;
}
This is the according child class:
class ChildClass {
void Function1(baseStruct& structVal);
void Function2(baseStruct& structVal);
}
Now i want to be able to call either of those functions with different structs, which have baseStruct as a parent like this:
childStruct1 cS1;
cS1.someInt1 = 5;
CS1.someInt2 = -3;
Function1(cS1);
The compiler is not complaining, but when i step through my program i noticed that the struct is filled with values before the function, but as soon as i step into my function the struct is empty. Now my first impression would be, that this happens because it gets "casted" to a baseStruct, which is empty.
Is there a way to achieve something like this, or am i doing something wrong? Maybe this is even possible and i fucked up somewhere else, but then why does the debugger say its empty?
Thank you!
The struct you see in the debugger is empty because when you enter Function1 the debugger 'forgets' any info about cs1 and knows just about baseStruct (which is empty).
If you do something like
childStruct *cs1 = reinterpret_cast<childStruct1>(&structVal) ;
yoy should see everything there.
But this takes to the real problem of you design: how do you tell, inside Funtion1 if you have received a childStruct1 or childStruct2?
What would be a good approach to implement a class in c++ like this:
Someclass.h:
class SomeClass
{
public:
SomeClass();
void kill();
}
Someclass.cpp:
SomeClass::kill(){
kill();//This would cause an infinit recursion
//How to fix it?
}
So what I'm trying to do is redeclare a function within my object as a method.
I can't find if there is a namespace or something simular, that contains "kill()", "sleep(int sec)".
Hope you can help.
SomeClass::kill(){
::kill();
}
:: accesses global scope
Suppose I have a bunch of fruit:
class Fruit { ... };
class Apple : public Fruit { ... };
class Orange: public Fruit { ... };
And some polymorphic functions that operate on said fruit:
void Eat(Fruit* f, Pesticide* p) { ... }
void Eat(Apple* f, Pesticide* p) { ingest(f,p); }
void Eat(Orange* f, Pesticide* p) { peel(f,p); ingest(f,p); }
OK, wait. Stop right there. Note at this point that any sane person would make Eat() a virtual member function of the Fruit classes. But that's not an option, because I am not a sane person. Also, I don't want that Pesticide* in the header file for my fruit class.
Sadly, what I want to be able to do next is exactly what member functions and dynamic binding allow:
typedef list<Fruit*> Fruits;
Fruits fs;
...
for(Fruits::iterator i=fs.begin(), e=fs.end(); i!=e; ++i)
Eat(*i);
And obviously, the problem here is that the pointer we pass to Eat() will be a Fruit*, not an Apple* or an Orange*, therefore nothing will get eaten and we will all be very hungry.
So what I really want to be able to do instead of this:
Eat(*i);
is this:
Eat(MAGIC_CAST_TO_MOST_DERIVED_CLASS(*i));
But to my limited knowledge, such magic does not exist, except possibly in the form of a big nasty if-statement full of calls to dynamic_cast.
So is there some run-time magic of which I am not aware? Or should I implement and maintain a big nasty if-statement full of dynamic_casts? Or should I suck it up, quit thinking about how I would implement this in Ruby, and allow a little Pesticide to make its way into my fruit header?
Update: Instead of the contrived bit with the bare Eat functions and Pesticide, suppose instead that I just don't want to put Eat in the fruit because it makes no sense. A fruit that knows how to eat itself? Pshaw. Instead I need an Eater class with an Eat function, with different code for eating each kind of fruit, and some default code in case it's a fruit that the eater doesn't recognize:
class Eater
{
public:
void Eat(Apple* f) { wash(); nom(); }
void Eat(Orange* f) { peel(); nom(); }
void Eat(Fruit* f) { nibble(); }
};
...
Eater me;
for(Fruits::iterator i=fs.begin(), e=fs.end(); i!=e; ++i)
me.Eat(*i); //me tarzan! me eat!
But again, this doesn't work, and the straightforward solution in C++ seems to be a bunch of calls to dynamic_cast.
However, as one of the answers suggests, there may be another clever solution. What if Fruits exposed the qualities that mattered to eaters, with functions like MustPeel() and MustWash()? Then you could get by with a single Eat() function ...
Update: Daniel Newby points out that using Visitor also solves the problem as presented ... but this requires a bit of a semantic headstand (Fruit::use or Fruit::beEaten?).
While I'd like to accept several answers, I think psmears's answer is actually the best one for future readers. Thanks, everyone.
You need to redesign. Namely, do everything you seem to be avoiding (for what reason, who knows.)
Polymorphic behavior requires polymorphic functions. This means a virtual function. (Or your ladder of dynamic_cast's, which completely defeats the purpose...)
// fruit.h
class Pesticide; // you don't need a complete type
struct Fruit
{
virtual void Eat(Pesticide*) = 0;
};
// apple.h
class Apple : public Fruit
{
void Eat(Pesticide* p) { ... }
};
// orange.h
class Orange : public Fruit
{
void Eat(Pesticide* p) { ... }
};
If you still want a free function*:
void Eat(Fruit* f, Pesticide* p) { f->Eat(p); }
*Note that your post is already indicative of bad design; namely the first Eat function:
void Eat(Fruit* f, Pesticide* p) { }
When does doing nothing to a fruit equate to eating the fruit? A pure virtual function is a much better interface choice.
When a question like this comes up, it's good to look at exactly why you want to make particular decisions - for instance, why do you not want the Fruit classes to know about Pesticide?
I'm sure there is a good reason for this - but expressing that reason will help clarify in your mind exactly what your aims are - and this often sheds a new light on a possible angle for structuring the program.
For instance, you might end up adding new virtual methods "IsEdible" and "PrepareForEating". Then you can implement these for each fruit, and implement one generic Eat method that works for all fruits - and ingests the pesky pesticide too - all without the Fruit classes knowing anything about it.
Of course, depending on your precise aims, that may be totally inappropriate - which is why you'll have to clarify the example in your own head :-)
Just use the I Am Standing Right Here! Pattern. It's like the Visitor Pattern but without a container.
// fruit.h
class Fruit;
class Apple;
class Orange;
class Fruit_user {
public:
Fruit_user();
virtual ~Fruit_user();
virtual use(Apple *f) = 0;
virtual use(Orange *f) = 0;
};
class Fruit {
public:
// Somebody with strong template fu could probably do
// it all here.
virtual void use(Fruit_user *fu) = 0;
};
class Apple : public Fruit {
public:
virtual void use(Fruit_user *fu) {
fu->use(this);
}
};
class Orange: public Fruit {
public:
virtual void use(Fruit_user *fu) {
fu->use(this);
}
};
// dow-chemical.h
class Pesticide_fruit_user : public Fruit_user {
public:
Pesticide_fruit_user(Pesticide *p) {
p_ = p;
}
virtual void use(Apple *f) { ingest(f, p_); }
virtual void use(Orange *f) { peel(f, p_); ingest(f, p_); }
private:
Pesticide *p_;
};
There's nothing wrong with having arbitrary class pointers in headers. They form the basis of many idioms, like PIMPL and opaque pointers. Also, if you aren't a sane person, how are you supposed to understand my answer?
Seriously, derived functions and polymorphism exist to solve this problem. If you refuse to use the language provided tools, why bother using it at all? Any solution you can come up with can be translated into a virtual function call in any case, just you would have coded it manually instead of having the compiler do it.
What you're asking for isn't possible. The function overloading resolution needs to know at compile time which class the parameter is so it can call the correct Eat function. The only exception is for virtual member functions, which you've already ruled out.