2011-08-24 107 views
1

我在C++中有一个依赖于原始指针的向量类。我不使用std :: vector,因为我需要从特定情况下的原始指针创建矢量对象。这是我的类的非常简单的例子:C++和运算符中的自定义向量和矩阵类[]

template <typename T> 
class Vector 
{ ... 
    private: 
    T * m_data; int m_size; bool dontFree; ... 
    public: 
    Vector(T *const ptr, int size) { m_data = ptr; m_size = size; dontFree = true; } 
    Vector(int size, T val) { ... dontFree = false; } 
    ~Vector(): { if(!dontFree) delete [] m_data; } 
    T& operator[](const size_type index); 
}; 

同样地,我有矩阵数据类型,同样在原始指针,并且可以使用向量存储数据,以支持[] [],因为它不是在C不允许++,像:

template<typename T> 
class Matrix 
{ 
    private: 
    T * m_data; ... 

public: 
    ... 
    Vector<T>& operator[](const int rowIndex) 
    { 
    return Vector<T>(&m_data[rowSize * rowIndex], rowSize); 
    } 
} 

怎么能我也有效地实现operator []的矩阵returing一个向量,这样我可以写代码,东西如下:

Matrix<int> m(5,5); 
m[1][1] = 10; 
int temp = m[1][2]; 

请建议考虑到c的开销opy构造函数等。

+0

通过复制返回载体,而不是引用,这是无效的几个原因。复印很便宜,甚至可能完全被优化。 –

+0

你能更好的解释为什么你不能使用'std :: vector'吗?内存范围['m_data','m_data + size']是否已分配?可能是一个C++ 1x移动构造函数解决你的问题。 –

+1

@Wiso:我认为这里的想法是创建矩阵的“切片视图”,它允许您将行和列视为一维向量。用辅助类做这件事很好,它应该是有效的,因为你不需要移动任何实际的数据。 –

回答

3

创建一个代理类,重载operator [],您可以访问矩阵的数组。事情是这样的:

template<typename T> 
class Proxy 
{ 
public: 
    Proxy(T * tp) 
     :rowStart(tp) 
    {} 

    T & operator[](const int columnIndex) 
    { 
     return rowStart[columnIndex]; 
    } 

private: 
    T * rowStart; 
}; 

然后你Matrix类的操作[]可以返回其中的一个,像这样:

Proxy<T> operator[](const int rowIndex) 
{ 
    return Proxy<T>(m_data + rowSize * rowIndex); 
} 

这不是完整的课程,但它应该让你开始。

+0

谢谢,但你能解释为什么使用Vector 类代替Proxy不好吗? – usman

+1

您的原始'Vector 'class *作为代理行事,因此它是相似的。我会尽量避免它(呃,实际上'Vector '和任何其他代理)由于其他原因。特别是重复使用'Vector '来有时管理资源,有时不会成为未来问题的根源(即类不变量根据类的使用位置不同而不同,这意味着它们不是真正的*不变量*) –

1

您应该通过值返回向量,使您的代码正确。如果你的向量在复制构造函数中做了很多工作,你也可以写一个小代理。

如果您将operator[]作为内联方法实施(例如,不要将实现移至cpp),那么优秀的编译器应优化您的代码并消除不必要的复制。

但如果你是疯狂的表现,那么你可以从运营商返回原始指针:

... 
T* operator[](const int rowIndex) 
{ 
    return m_data + rowSize * rowIndex; 
} 
... 
int temp = m[1][2]; 

不过是一个危险的方法!

0

实施多维矩阵时的建议不是过载operator[],而是将过载operator()与多个维度。有迹象表明,你可以在C++ FAQ lite

template <typename T> 
class Matrix { 
public: 
    typedef std::size_t size_type; 
    typedef T & reference; 
    typedef T const & const_reference; 

    const_reference operator()(size_type x, size_type y) const; 
    reference operator()(size_type x, size_type y); 
}; 
阅读