Suppose I have the following class:
class DX11ConstantBuffer
{
public:
ID3D11Buffer *pData;
};
I receive an array of this class in a function:
DX11ConstantBuffer **pp
My wrapper (DX11ConstantBuffer) contains a pointer to ID3D11Buffer. The following function:
pDevcon->VSSetConstantBuffers
requires a pointer to an array of ID3D11Buffers,
ID3D11Buffer *const *ppConstantBuffers
As the function receives a pointer to an array of my own wrapper, what would be the fastest way to create an array of ID3D11Buffers from it? To make it clearer:
void ...(DX11ConstantBuffer **pp, ....)
{
ID3D11Buffer** _pp = GetAllID3D11BufferElementsFrom(pp);
pDevcon->VSSetConstantBuffers(..., _pp, ...);
}
The function is meant to be called several times each frame.
The fastest way is proactively, i.e. to have maintained a contiguous array of ID3D11Buff* before needing to call VSSetConstantBuffers, for which you'd want a std::vector<ID3D11Buff*>. You could update the vector whenever DX11ConstantBuffer::pData is set, or DX11ConstantBuffer's destructor runs, and if you want better assurances around that you can make pData private and have accessor functions which can reliably intercept changes.
If you don't do it proactively, then with your current objects you've no choice but to iterate over the DX11ConstantBuffers and copy out the ID3D11Buf*s to an array/vector one-by-one....
You can make the wrapper inherites from the type it includes.
Related
I have 3 classes. DrawGameComp' and 'GameComp' where 'GameComp' is the base class of 'DrawGameComp'. I have an array of pointers in Game class which is the controlling class. '
GameComp * components[]; From the main I have to create a dynamic instance of Game and store add new objects of GameComp and DrawGameComp to the array of pointers of type GameComp.
Game Game1(2);
Game1.Add(new GameComponent);
Game1.Add(new DrawableGameComponent);
I'v done this part in the main. Because from the main I have to invoke Add passing object as the parameter. When i store these objects I also want assign an id of 1 to the first object and an id of 2 to the second object. How can i include that too.
The Add() function of my Game class is as follows
void Game::Add(GameComponent*)
{
components[0]=GameComp;
componentCount++;
}
but it give me error. I have tried so hard. But I couldn't. Also how do I invoke the Display() member function of these objects in the Array? is it this way?
components[0]->Display();
The Add method should look like:
void Game::Add(GameComponent* comp)
{
components[componentCount++] = comp;
}
Make sure you zero out componentCount in the constructor.
Using the array:
components[i]->DoSomething();
1) You probably meant to write the following:
void Game::Add(GameComponent* comp)
{
components[componentCount++] = comp;
}
2) components[0]->Display() will work, if display is a member function of GameComponent class.
My main program is to generate a random number to create movement of a object in a 2 dimensional array and to keep track of it.
one of my function void current_row(int row){position = row}; keeps track of the current row of the object.
since the variable is not global. i am finding problems calling the current location and updating it to the next movement. this is how the other function may look like:
void movement (){
int row;
row = current_row();
/*
* Here is the problem i'm having. This may well be
* a third function which has the same information
* as my first function. But still how do I access
* once without modifying it and access it
* again to update it?
*/
// call another function that creates new row.
// update that info to the row
}
i am new to c++.
Use an instance variable to keep track of it. That's why instance variables exist: To hold their values between function calls.
In case it's an OOP environment (as C++ tag implies), some class should declare int row as a class member (including a getter and a setter as methods).
Another option is declaring the variable at the head of the main() part of the program and call functions with row as a function parameter.
void movement(int row)
{
}
You can consider the parameter be passed by reference if you are intending to change it, otherwise it would be better declaring it const inside the function parameter declaration. If part of the answer sounds unfamiliar to you I would suggest reading through :
What's the difference between passing by reference vs. passing by value?
I have a data buffer stored in a shared_ptr<void>.
This buffer is organized in several encapsulated layers so that I end up with:
-----------------------------------...
- Header 1 | Header 2 | Data
-----------------------------------...
(Actually it's an Ethernet packet where I decapsulate the layers one after the other).
Once I read Header 1, I would like to pass the rest of the packet to the next layer for reading, so I would like to create a pointer to :
-----------------------...
- Header 2 | Data
-----------------------...
It would be very easy with a raw pointer, as it would just be a matter of pointer arithmetic. But how can I achieve that with a shared_ptr ? (I use boost::shared_ptr) :
I cannot create a new shared_ptr to "first shared_ptr.get() + offset" because it makes no sense to get the ownership to just Header 2 + Data (and delete would crash eventually)
I do not want to copy the data because it would be silly
I want the ownership on the whole buffer to be shared between the two objects (ie. as long as the parent object or the one which requires only Header 2 needs the data, the data should not be deleted).
I could wrap that up in a structure like boost::tuple<shared_ptr<void>, int /*offset*/, int /*length*/> but I wonder if there is a more convenient / elegant way to achieve that result.
Thanks,
I would recommend encapsulating the layers each in a class that knows how to deal with the data as though it were that layer. Think each one as a view into your buffer. Here is a starting point to get you thinking.
class Layer1{
public:
Layer1(shared_ptr<void> buffer) : buffer_(buffer) { }
/* All the functions you need for treating your buffer as a Layer 1 type */
void DoSomething() {}
private:
shared_ptr<void> buffer_;
};
class Layer2{
public:
Layer2(shared_ptr<void> buffer) : buffer_(buffer) { }
/* All the functions you need for treating your buffer as a Layer 2 type */
void DoSomethingElse() {}
private:
shared_ptr<void> buffer_;
};
And how to use it:
shared_ptr<void> buff = getBuff(); //< Do what you need to get the raw buffer.
// I show these together, but chances are, sections of your code will only need
// to think about the data as though it belongs to one layer or the other.
Layer1 l1(buff);
Layer2 l2(buff);
l1.DoSomething();
l2.DoSomethingElse();
Laying things out this way allows you to write functions that operate solely on that layer even though they internally represent the same data.
But, this is by no means perfect.
Perhaps Layer2 should be able to call Layer1's methods. For that you would want inheritance as well. I don't know enough about your design to say whether that would be helpful. Other room for improvement is replacing the shared_ptr<void> with a class that has helpful methods for dealing with the buffer.
can you just use a simple wrapper?
something like this maybe?
class HeaderHolder : protected shared_ptr<void> {
public:
// Constructor and blah blah
void* operator* () {
offset += a_certain_length;
return (shared_ptr<void>::operator*() + offset);
}
};
By the way, I just used a simple wrapper that I reproduce here if someone ever stumbles on the question.
class DataWrapper {
public:
DataWrapper (shared_ptr<void> pData, size_t offset, size_t length) : mpData(pData), mOffset(offset), mLength(length) {}
void* GetData() {return (unsigned char*)mpData.get() + mOffset;}
// same with const...
void SkipData (size_t skipSize) { mOffset += skipSize; mLength -= skipSize; }
void GetLength const {return mLength;}
// Then you can add operator+, +=, (void*), -, -=
// if you need pointer-like semantics.
// Also a "memcpy" member function to copy just this buffer may be useful
// and other helper functions if you need
private:
shared_ptr<void> mpData;
size_t mOffset, mLength;
};
Just be careful when you use GetData: be sure that the buffer will not be freed while you use the unsafe void*. It is safe to use the void* as long as you know the DataWrapper object is alive (because it holds a shared_ptr to the buffer, so it prevents it from being freed).
I have following classes: Container, Element and then couple of classes that inherit from Element, eg. Button, Input, etc ...
I have a problem when adding the elements to Container array, my main() looks like this:
Container c;
c.Add( Button(...) );
c.Add( Input(...) );
where "..." are some constructor parameters.
In the container class I have a array of pointers to store all elements that belong to that container:
Element ** elements;
But the problem I'm having is how to implement the Add method, I was hoping something like this would work:
void Add(const CControl & newElement){
elements[elemCnt++] = &newElement;
}
(the elements array is allocated: elements = new Element * [100];)
However I am getting this compilation error:
main.cpp: In member function ‘Container& Container::Add(const Element&)’:
main.cpp:138:23: error: invalid conversion from ‘const Element*’ to ‘Element*’
When I remove the const qualifier, I get a compilation error saying there is no suitable candidate.
The thing is, I am new to polymorphism and inheritance in C++, so I might be going wrong way about this. What would be the best approach on this?
PS: The main method must look the same, also don't suggest any vector or STL stuff.
Add should take a pointer:
void Add(CControl * newElement){
elements[elemCnt++] = newElement;
}
then you can call it like this
c.Add( new Button(...) );
c.Add( new Input(...) );
If you really cannot change the calling code, you need to somehow create a copy of the temporary.
E.g. by implementing a virtual Clone method in CControl, Input, Button an call it in Add.
void Add(const CControl & newElement){
elements[elemCnt++] = newElement.Clone();
}
It is impossible to fix this code without changing main, because you attempt to store a reference to a temporary. This is undoable no matter what you do.
I am trying to store a vector(or stack) of functions. The idea is that I have a series of functions that add & remove widgets to the main window. I use a timer alarm & whenever the alarm is called I call the function at the top of the stack of functions.
So my functions will always be of type void. My problem/misunderstanding is how to delcare a stl::stack of void functions & how do I execute that function?
class InstructionScreen
{
std::stack <void*> instructionSteps; // is this how I declare a stack of functions
void runTimerEvent()
{
if ( !instructionSteps.empty() )
{
// call the function at the top of the stack
// how do I call the function?
(*instructionSteps.top()); // is that how?
instructionSteps.pop();
}
}
void step1()
{
// here I create some widgets & add them to the main window
}
void step2()
{
// delete widgets from window
// create some different widgets & add them to the main window
}
void buildStack()
{
instructionSteps.push( (&step1()) ); // is this correct?
instructionSteps.push( (&step2()) );
}
};
A void* pointer is not a legal function pointer. It should be void (*)(), which can be made nicer with a typedef void (*stack_function)().
std::stack<stack_function> instructionSteps;
To push something into it, you don't call the function (like you do with step1()) and you certainly don't take the address of the return (which is void anyways) like you do with &step1(), you just use the function name alone:
instructionSteps.push(step1); // the & can be omitted for free functions
instructionSteps.push(&step2); // equivalent to the above, only a different function
To call stuff from the top of the stack, you actually need to do a call:
(*instructionSteps.top())();
// you missed that -- ^^
The dereference can be omitted too for reasons that would take too long to explain here, search SO. :)
instructionSteps.top()();
The syntax for a static function pointer is like so:
void (*FuncPtr)();
For a member pointer you have to use this syntax:
void (class::*FuncPtr)();
If your functions does not require the functions to be member functions it is a lot cleaner. Once you figured out what kind of functions you need it's easiest to typedef these functions like so:
typedef void(*FuncPtrType)();
typedef void(Class::*MemberFuncPtrType)();
Now you can simply declare a stack with function pointers like so:
std::stack <FuncPtrType> funcPtrStack;
std::stack <MemberFuncPtrType> memberFuncPtrStack;
To get a pointer to a function you simply use the "&" operator like you would to get an address to any other data type in C++:
FuncPtrType funcPtr = &staticFunc; // Somewhere "void staticFunc()" is defined
MemberFuncPtrType memberFuncPtr = &Class::MemberFunc; // Somewhere void "Class::MemberFunc()" is defined
To actually call the function pointers, you would use the "*" operator to get the data back from the pointer (just like any other data type in C++). The only tricky thing is for member functions they need a pointer to the class which makes it very awkward to use. That's why I recommended using static functions to begin with. In any case, here is the syntax:
(*funcPtr)(); // I just called a function with a pointer!
(this->*memberFuncPtr)(); // I just wrote some ugly code to call a member function
Having shown all that, the following code should now make sense:
std::stack <MemberFuncPtrType> memberFuncPtrStack; // Declaring the stack
memberFuncPtrStack.push( &Class::MemberFunc ); // Pushing a function
(ClassPtr->*memberFuncPtrStack.top())(); // Calling the function with ClassPtr
Declare a typedef and make a vector/stack of it:
typedef void (*funcptr)();
std::stack<funcptr> instructionSteps;
Usage:
instructionSteps.push(&step1);
instructionSteps.push(&step2);
See demo here.
Execution:
instructionSteps.top()();
Tip: Use Boost.Function, it's a lot easier. It will not only store functions with precisely the right type, but also anything else that can be called in the same way.
std::stack<boost::function<void()> instructionSteps;
int foo() { return 42; }
instructionSteps.push(foo); // Close enough - return value will be discarded.
typedef void (*fptr)();
class InstructionScreen
{
std::stack <fptr> instructionSteps;
I would typedef the function pointer to make your life easier:
typedef void(*voidFunctionPointer)(); // Assuming here that the functions take no arguments.
std::stack<voidFunctionPointer> instructionSteps; // This is very different from <void*>.
// The latter is merely a stack of void pointers.
One way of calling the top function is this:
voidFunctionPointer functionToCall = instructionSteps.top();
functionToCall();
If you want to do it without an extra declaration, I think this should work. Please correct me if I'm wrong.
instructionSteps.top()();
To build the stack, just use the function name without any trailing parentheses.
instructionSteps.push(step1);
instructionSteps.push(step2);
// ...