【问题标题】:Initializing an array in a object in C++在 C++ 中初始化对象中的数组
【发布时间】:2020-12-10 07:06:32
【问题描述】:

我目前正在学习 C++,并创建了一个小数组类。

问题:我无法用构造函数初始化对象中的数组。

我需要写什么来初始化这个成员? (我确信语法有问题。)

代码:

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;
}

【问题讨论】:

  • 能否添加错误信息?
  • 它说“语法错误,预期的;”
  • 哪一行?请尽可能具体。如有疑问,只需复制并粘贴整条消息
  • 提示:声明中的每一行都需要;。当编译器提醒您此类问题时,请检查错误引用的哪一行并确保它被正确终止。
  • 好的,但它是德语:错误 C2143: Syntaxfehler: Es fehlt ";" vor "

标签: c++ arrays class templates syntax


【解决方案1】:

您实现的构造函数需要一个int* 指针作为输入,但{2, 3, 4} 不会衰减为int*,所以不,鉴于您目前已经实现的类,您显示的语法将不起作用。

如果您在编译时知道确切的数组大小,则可以改用std::array

#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;
}

否则,如果你真的想让ary有一个指向一些数组数据的指针,你可以先声明一个实际的数组,然后将它传递给构造函数,例如:

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;
};

但请考虑为您的类提供一个以std::initializer_list 作为输入的构造函数,然后让该类在内部分配自己的数组(请务必遵循Rule of 3/5/0),例如:

#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;
}

更好的选择是改用std::vector,让它为您完成所有工作,例如:

#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;
}

【讨论】:

  • 在现实世界中,您将直接使用std::arraystd::vector。无需围绕它构建包装器。另外为什么不建议最明显的解决方案? struct Array { T data[SIZE]; }
  • "无需围绕它构建包装器" - 这取决于您要添加的额外功能。封装是有道理的。 “为什么不建议最明显的解决方案?struct Array {T data[SIZE]; }” - 补充道。
【解决方案2】:

构造函数:

ary<T_datatype> ... 

应该简单命名:

ary ... 

即没有模板参数。

main 中的行:

ary<int> array_int = {2, 3, 4};

期望获得三个ints 的构造函数或获得std::initializer_list&lt;int&gt; 的构造函数,它们都不存在于您的类中。

【讨论】:

  • 这仍然无法编译。您不能将大括号初始化列表传递给期望指针的构造函数。
  • 好吧,好吧,猜猜我们等待 OP 针对该错误发布一个新问题 :)
  • 构造函数中的&lt;T_datatype&gt;不必要但无害。
  • @cigien 我会接受你对这些事情的了解!但是,MSVC 和 clang-cl(设置为使用“预览版”C++20 标准)都接受它。
  • @AdrianMole 嗯,我很确定我在某处听说过。 gcc 最近开始报错,所以我问了question 以确保。
【解决方案3】:

不幸的是,C++ 不允许compound literals - C 语言的一个特性在此处可能很有用。相反,您需要将数组“参数”声明为构造函数本身的变量,然后将其传递给构造函数:

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;
}

【讨论】:

    猜你喜欢
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多