Inicializar una matriz en un objeto en C ++
Actualmente estoy aprendiendo C ++ y creé una pequeña clase de matriz.
Problema: no puedo inicializar la matriz en el objeto con el constructor.
¿Qué necesito escribir para inicializar este miembro? (Estoy seguro de que algo con la sintaxis está mal).
Código:
ary.h
:
template<typename T_datatype>
class ary {
private:
T_datatype* T_dataptr;
public:
ary<T_datatype>(T_datatype* T_ptr) : T_dataptr(T_ptr) {}
};
main.cpp
:
#include "ary.h"
int main()
{
ary<int> array_int = {2, 3, 4}; //is it something like that?...
return 0;
}
Respuestas
El constructor que ha implementado espera un int*
puntero como entrada, pero {2, 3, 4}
no decae a un int*
, así que no, la sintaxis que ha mostrado no funcionará dada la clase que ha implementado hasta ahora.
Si conoce el tamaño exacto de la matriz en tiempo de compilación, puede hacer esto usando en su std::arraylugar:
#include <array>
template<typename T, size_t N>
struct ary {
std::array<T, N> data;
...
};
#include "ary.h"
int main()
{
ary<int, 3> array_int1{2, 3, 4};
ary<int, 3> array_int2 = {2, 3, 4};
ary<int, 3> array_int3 = {{2, 3, 4}};
return 0;
}
De lo contrario, si realmente desea ary
tener un puntero a algunos datos de la matriz, puede declarar una matriz real primero y luego pasarla al constructor, por ejemplo:
template<typename T>
class ary {
private:
T *dataptr;
...
public:
ary(T* ptr) : dataptr(ptr) {}
...
};
#include "ary.h"
int main()
{
int data[] = {2, 3, 4};
ary<int> array_int(data);
...
return 0;
};
Pero considere darle a su clase un constructor que tome std::initializer_listcomo entrada en su lugar, y luego haga que la clase asigne su propia matriz internamente (solo asegúrese de seguir la Regla de 3/5/0 ), por ejemplo:
#include <algorithm>
#include <utility>
template<typename T>
class ary {
private:
T *dataptr = nullptr;
int datasize = 0;
public:
ary() = default;
ary(const ary &src)
: ary()
{
if (src.dataptr && src.datasize > 0)
{
dataptr = new T[size];
datasize = src.datasize;
std::copy(src.dataptr, src.dataptr+src.datasize, dataptr);
}
}
ary(ary &&src)
: dataptr(src.dataptr), datasize(src.datasize)
{
src.dataptr = nullptr;
src.datasize = 0;
}
ary(T* ptr, int size)
: dataptr(new T[size]), datasize(size)
{
std::copy(ptr, ptr+size, dataptr);
}
ary(std::initializer_list<T> l)
: dataptr(new T[l.size()]), datasize(l.size())
{
std::copy(l.begin(), l.end(), dataptr);
}
~ary()
{
delete[] dataptr;
}
ary& operator=(ary rhs)
{
std::swap(dataptr, rhs.dataptr);
std::swap(datasize, rhs.datasize);
return *this;
}
...
};
#include "ary.h"
int main()
{
ary<int> array_int1;
ary<int> array_int2 = {2, 3, 4};
int data[] = {2, 3, 4};
ary<int> array_int3{data, 3};
ary<int> array_int4{array_int2};
ary<int> array_int5{std::move(array_int3)};
...
return 0;
}
Una mejor opción es usar std::vectoren su lugar y dejar que haga todo el trabajo por usted, por ejemplo:
#include <vector>
template<typename T>
class ary {
private:
std::vector<T> data;
public:
ary() = default;
// the copy/move constructors, copy/move assignment operators,
// and destructor will be implicitly generated for you...
ary(T* ptr, int size) : data(ptr, size) {}
ary(std::initializer_list<T> l) : data(l) {}
...
};
#include "ary.h"
int main()
{
ary<int> array_int1;
ary<int> array_int2 = {2, 3, 4};
int data[] = {2, 3, 4};
ary<int> array_int3{data, 3};
ary<int> array_int4{array_int2};
ary<int> array_int5{std::move(array_int3)};
...
return 0;
}
El constructor:
ary<T_datatype> ...
debe nombrarse simplemente:
ary ...
es decir, sin el parámetro de plantilla.
La línea en main:
ary<int> array_int = {2, 3, 4};
está esperando un constructor que obtenga tres int
so un constructor que obtenga que std::initializer_list<int>
ninguno de ellos exista en su clase.
Desafortunadamente, C ++ no permite literales compuestos , una característica del lenguaje C que podría ser útil aquí. En su lugar, deberá declarar su 'argumento' de matriz al constructor como una variable por derecho propio, luego pasarlo al constructor:
int main()
{
// ary<int> array_int = { 2, 3, 4 }; //is it something like that?...
int data[] = { 2, 3, 4 };
ary<int> array_int{ data }; // "data" will here decay into a pointer to its first element
return 0;
}