C ++ click on 3 different vectors with one common method

I'm new to C ++ and I find the whole concept of pointers, double pointers and references to be confusing.

I am writing an object loader for assignment and came to the part where I want to optimize / modular solution.

Right now I have 3 vectors that contain information about object texture coordinates, faces and normals. Instead of doing an operation for each one, I want to simplify my codebase by introducing a method to handle clicking on the following vectors.

std::vector<XMFLOAT3> vert_texture_coord;
std::vector<XMFLOAT3> vert_normals;
std::vector<XMFLOAT3> vert_position;

      

Currently, I write to them like this:

vert_text_coord.push_back(XMFLOAT3(vert_x, vert_y, vert_z));

      

But modularly I wrote a method:

push_to_vector(float x, float y, float z, *vector)
{
    // push code here
}

      

Call this type

push_to_vector(vert_x, vert_y, vert_z, &vert_text_coord);

      

Am I right to pass a reference vert_text_coord

to a pointer parameter *vector

in my method push_to_vector

, or am I doing it wrong? Finally, would it also make sense to have parameters vert_x, vert_y, vert_z

as references, or have I completely misunderstood the concept &

?

Thanks in advance.

+3


source to share


4 answers


In fact, I think you are asking the wrong question here. Yes, you can perfectly pass a pointer / reference to a function that pushes XMFLOAT3

towards the end of the vector, the working code will be

//function signature:
push_to_vector(std::vector<XMFLOAT3>* v, float x, float y, float z);

//call:
push_to_vector(&ver_normals, x, y, z);

      

or using links

//function signature:
push_to_vector(std::vector<XMFLOAT3>& v, float x, float y, float z);

//call:
push_to_vector(ver_normals, x, y, z);

      

However, as I said, this answers the wrong question. The right question is: would the idea of ​​a function be push_to_vector()

good? And I believe it isn't. The reason is that the function push_to_vector()

is not the correct abstraction. The code that uses your three vectors will never want to abstract away from which vector it is using, it will want to abstract from the fact that it is using a vector.

It's bad to have functions that are too long, but it's also bad to have tons of one-line functions like a function push_to_vector()

. Each function should strive to have a sufficiently large difference in the level of abstraction between what it uses and what it provides. If this is not the case, you will get lost in the deep call hierarchies that you create.

(It's no coincidence that it has winning entries that either combine everything into one function, or have something like 50 functions, each only a few characters long. Either method is equally effective at obfuscating code.)




Here are my two cents when asked if it is better to use pointers or links:

Consider the following five functions:

void foo(int x);
void bar(int& x);
void baz(int* x);
void bim(const int& x);
void bam(const int* x);

      

and their corresponding calls:

int var = 7;
foo(var);    //may not change var
bar(var);    //may change var
baz(&var);   //may change var
bim(var);    //may not change var
bam(&var);   //may not change var

      

The first call is the normal case in C ++ and it cannot change its argument since it uses a pass by value. I think it's a really good idea if you can see right away that the call will change its argument. So I am limited to either using pass by value, pass by pointer, or passing using const

reference, i. e. these three options:

foo(var);    //may not change var
baz(&var);   //may change var, visible by the take-address operator
bim(var);    //may not change var, pass by value semantics optimized via a const reference

      

+2


source


&

takes the address of the object, so when you write &vert_text_coord

you getvector*

To pass by reference, you need to have a reference parameter to the function.

push_to_vector(float x, float y, float z, vector& vec)
{
   vec.push_back(x,y,z);
}

      



Then you can call the function as usual.

push_to_vector(vert_x, vert_y, vert_z, vert_text_coord);

      

+1


source


So far, it looks like you have the right idea.

Correction: the pointer parameter in the function looks like T*

, not *T

. So your push_to_vector

fucntion will look like this:

push_to_vector(float x, float y, float z, std::vector<XMFLOAT3>* v)

Also, unless you plan on changing x, y and z, there is no need to pass them by reference.

EDIT: As the answer about cocaine says, following the link here is really the correct way to do it.

Also as a side note, it looks like it would be nice to wrap all your vectors in a class. This way you don't have to toss these vectors around in the function a lot.

+1


source


Learn to declare function parameters correctly. Since your function mimics the push_back method which is written as

vert_text_coord.push_back(XMFLOAT3(vert_x, vert_y, vert_z));

      

then the first parameter must be a vector reference. for example

void push_to_vector( std::vector<XMFLOAT3> &, float, float, float );

      

In this case, you can, for example, declare some parameters as having default arguments. for example

void push_to_vector( std::vector<XMFLOAT3> &, float = 0.0f, float = 0.0f, float = 0.0f );

      

And this function can be called like

push_to_vector( vert_text_coord, vert_x, vert_y, vert_z );

      

Or if you declare some default arguments like

push_to_vector( vert_text_coord );

      

You can even change the default arguments for a function by reusing the function in a given (e.g. block) scope.

It also makes no sense to declare float parameters as references.

You can use the default argument for the last parameter as a label where only two parameters are to be used inside the function.

void push_to_vector( std::vector<XMFLOAT3> &, float, float, float = 0.0f );

      

The function can be called either as

push_to_vector( vert_text_coord, vert_x, vert_y, vert_z );

      

or

push_to_vector( vert_text_coord, vert_x, vert_y );

      

In the latter case, vert_z woul would be 0.0f (or some other value), which would mean that the function itself should provide the required value.

+1


source







All Articles