Reputation: 26501
I need to return 3 values. X, Y, Z. I've tried something like this, but it does not work, can anyone help me a bit? I've looked here: Return a float array in C++ and I tried to do same thing, except with 1 dimensional array to return.
class Calculate
{
float myArray[3][4], originalArray[3][4], tempNumbers[4];
float result[3]; // Only works when result is 2 dimensional array, but I need 1 dimension.
public:
Calculate(float x1, float y1, float z1, float r1,
float x2, float y2, float z2, float r2,
float x3, float y3, float z3, float r3)
{
myArray[0][0] = x1;
myArray[0][1] = y1;
myArray[0][2] = z1;
myArray[0][3] = r1;
myArray[1][0] = x2;
myArray[1][1] = y2;
myArray[1][2] = z2;
myArray[1][3] = r2;
myArray[2][0] = x3;
myArray[2][1] = y3;
myArray[2][2] = z3;
myArray[2][3] = r3;
result[0] = 1;
result[1] = 2;
result[2] = 3;
}
float* operator[](int i)
{
return result[i]; //Value type does not match the function type
}
const float* operator[](int i) const
{
return result[i]; //Value type does not match the function type
}
};
Upvotes: 3
Views: 14506
Reputation: 25497
Some responses have indicated the use of pointers. The problem is who allocates that pointer and who frees it. Also one needs to check if the incoming pointer is NULL and so on. Instead I would suggest the following declaration of the constructor.
Calculate(float x1, float y1, float z1, float r1,
float x2, float y2, float z2, float r2,
float x3, float y3, float z3, float r3, float (&r)[3])
This is much more safer as references can not be NULL.
Upvotes: 0
Reputation: 27077
result[i]
is a float, not a float*, so you can do
const float operator[](int i) const
{
return result[i];
}
But I think you do want to return a reference to get the correct semantics, so you want
const float& operator[](int i) const
{
return result[i];
}
float& operator[](int i)
{
return result[i];
}
Right? (I think this is OK -- it compiles but it's been a while since I've done this...)
Upvotes: 2
Reputation: 57678
Another alternative is to make the result
as a separate structure and either return it as a value or pass it by reference:
struct Result_Type
{
double values[3];
// Alternatively:
// double x;
// double y;
// double z;
};
// Returning a result
const Result_Type calculate_result_1(/* yada yada yada */)
{
Result_type new_result;
new_result.value[0] = 0;
new_result.value[1] = 0;
new_result.value[2] = 0;
return result; // Return the result as a object
}
// Or passing a result to be modified
void clear_result(Result_Type & any_result) // <-- Note pass by reference
{
any_result.value[0] = 0;
any_result.value[1] = 0;
any_result.value[2] = 0;
return;
}
You may find that this is a preferred design since you can pass around results, modify the Result_Type
structure to perform operations with other result vectors (math term). The matrix can also be considered as a composition of result vectors.
This may make the code easier to read also.
Upvotes: 2
Reputation: 15221
Instead of returning a pointer, it's usually better practice to accept a pointer and write out the results there. That way someone can allocate a regular array on the stack and have it initialized by your Calculate.
Something like:
class Calculate
{
float myArray[3][4], originalArray[3][4], tempNumbers[4];
public:
Calculate(float x1, float y1, float z1, float r1,
float x2, float y2, float z2, float r2,
float x3, float y3, float z3, float r3, float *result)
{
myArray[0][0] = x1;
myArray[0][1] = y1;
myArray[0][2] = z1;
myArray[0][3] = r1;
myArray[1][0] = x2;
myArray[1][1] = y2;
myArray[1][2] = z2;
myArray[1][3] = r2;
myArray[2][0] = x3;
myArray[2][1] = y3;
myArray[2][2] = z3;
myArray[2][3] = r3;
result[0] = 1;
result[1] = 2;
result[2] = 3;
}
};
Some other tweaks you can do - separate the constructor from the calculation, since constructors are more for initialization; and pass arrays for safer memory control:
class Calculate
{
float myArray[3][4], originalArray[3][4], tempNumbers[4];
public:
Calculate(const float initArray[3][4])
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++)
myArray[i][j] = initArray[i][j];
}
void DoCalculation(float result[3]) const
{
result[0] = 1;
result[1] = 2;
result[2] = 3;
}
};
int main()
{
float myArray[3][4] =
{
{ 0, 1, 2, 3 },
{ 4, 5, 6, 7 },
{ 8, 9, 0, 1 }
};
float result[3];
Calculate calc(myArray);
calc.DoCalculation(result);
return 0;
}
Upvotes: 5
Reputation: 41331
In the code, where you are getting an error, you are not trying to return a pointer. You are trying to return a single float at the given index.
Calculate c;
float first = c[0];
float second = c[1];
float third = c[2];
If you meant to return a pointer to the results
array, then you would have to return the array, e.g
float* GetResult() { return result; }
It probably doesn't matter much which you'll keep because the end effect is pretty much the same. If you overload operator[]
, you'll have more control, though, as you can check out-of-bound accesses.
Upvotes: 0