名称后跟::必须是类或名称空间,但标头已定义

时间:2020-10-19 12:40:51

标签: c++ oop

我正在尝试实现一些在源文件的头文件中声明的方法。

我不断收到此错误

name followed by :: must be a class or namespace

从搜索看来,这似乎是项目设置错误,但是我的两个文件都位于正确的目录中。

主要

#include "sarray.h"
#include <iostream>
using namespace std;
template<class genericData>
sarray::sarray(int size)
{
    if (size > 0) genericData data = new int[size];
    else {
        cout << "illegal array size = " << size << endl;
        exit(1);
    }
}
template<class genericData>
sarray::~sarray()
{
    delete[] data;
}
template<class genericData>
int& sarray::operator[](int i)
{
    if (i < 0 || i >= size) {
        cout << "index " << i << " is out of bounds." << endl;
        exit(1);
    }
    return data[i];
}
int main()
{
    // create a 10-element safe array
    sarray myArray = sarray(10);
    sarray array(10);
    // in-bound access, [] is used on the left side or an assignment
    array[5] = 23;
    // in-bound access, [] is used on the right side of an operation
    cout << array[5] << endl;
    // out-of-bound accesses
    array[13] = 392;
    cout << array[-1] << endl;
    return 0;
}

sarray.h

#ifndef SARRAYS_H
#define SARRAYS_H

template<class genericData>
class sarray {
public:
    sarray(int size);
    ~sarray();
    & operator[](int i);
private:
    int size;
    genericData* data;
};
#endif // !sarrays

1 个答案:

答案 0 :(得分:1)

  • 您的成员函数实现也需要template参数:
    template<class genericData>
    sarray<genericData>::sarray(...) ...
    
  • 也将类模板成员函数的实现放在头文件中。如果您不这样做,那么在编译.cpp文件时,目标文件中将不生成任何内容。编译器不知道要实例化方法的类型。
  • 请勿使用using namespace std;-尤其是在头文件的全局范围内。它将强制使用到头文件的每个用户上。
  • 由于您的班级拥有无法使用默认的复制/移动构造函数安全地复制或移动的资源,因此delete就是这样。
  • 不要在边界检查功能中exit()。引发out_of_range异常。
  • 对数组大小使用无符号整数,例如size_t
  • 使用班级模板时,您需要提供要存储在其中的类型。

示例:

#ifndef SARRAYS_H
#define SARRAYS_H

#include <cstddef>
#include <cstdlib>
#include <stdexcept>
#include <string>

template<class genericData>
class sarray {
public:
    sarray(size_t size);
    sarray(const sarray&) = delete; // copying deleted
    sarray(sarray&&) = delete;      // moving deleted
    ~sarray();
    genericData& operator[](size_t i);

private:
    size_t size;
    genericData* data;
};

template<class genericData>
sarray<genericData>::sarray(size_t size) : // use the member initializer list
    size(size),                            
    data(new genericData[size])
{}

template<class genericData>
sarray<genericData>::~sarray() {
    delete[] data;
}

template<class genericData>
genericData& sarray<genericData>::operator[](size_t i) {
    if (i >= size) throw std::out_of_range(std::to_string(i));
    return data[i];
}

#endif
#include "sarray.h"

#include <iostream>

using namespace std;

int main()
{
    // create a 10-element safe array
    sarray<int> myArray = sarray<int>(10);
    sarray<int> array(10);
    // in-bound access, [] is used on the left side or an assignment
    array[5] = 23;
    // in-bound access, [] is used on the right side of an operation
    cout << array[5] << endl;
    // out-of-bound accesses
    array[13] = 392;

    cout << array[-1] << endl;
    return 0;
}