当数组是类的数据成员时,如何使用指针交换数组

时间:2016-01-18 23:51:31

标签: c++ arrays oop pointers

我试图通过交换指向两个数组的指针来交换数组中的内容。

我的方法与丹尼尔在这个问题中回答的方法相同:Swap arrays by using pointers in C++。但不同的是,我的数组将成为一个类中的成员。 我的代码可以成功编译,但输出结果非常奇怪。

这是我的头文件:

#include <stdio.h>
#include <iostream>

class Map
{
public:
    Map(int times); // Create an empty map (i.e., one with no key/value pairs)

    int size();     // Return the number of key/value pairs in the map.
    void dump();
    void swap(Map &other);
    int *retrieve();
    void setptr(int *newptr);

private:
    int *ptr;
    int array_1[5];
};

这是我的实施:

#include "Map.h"
#include <iostream>

using namespace std; 

Map::Map(int times) {
    for (int i = 0; i < 5; i++) {
        array_1[i]=i*times;
    }
    ptr=array_1;
}

void Map::dump() {
    ptr=array_1;
    for (int i = 0; i < 5; i++) {
        cout << *ptr << endl;
        ptr++;
    }
    for (int i = 0; i < 5; i++) {
        ptr--;
    }  
}

void Map::swap(Map &other) {
    int *temp;
    temp = this->ptr;
    this->ptr = other.retrieve();
    other.setptr(temp);
}

int *Map::retrieve() {
    return ptr;
}

void Map::setptr(int *newptr) {
    ptr=newptr;
}

谁能告诉我什么是错的以及如何巧妙地实施它?

2 个答案:

答案 0 :(得分:0)

您的设计存在的问题是指针指向同一对象中的数组。

假设你必须对象a和b。如果交换指针,a.ptr将指向包含数据的b.array_1。相反b.ptr将指向a.array1。

不幸的是,如果其中一个对象 - 比如b - 被破坏(因为它是一个超出范围的本地对象,或者出于任何原因),剩下的对象的指针将指向一个不具有的对象已经存在了。这是UB。

要解决您的问题,您需要在构造函数中动态分配数组。完全摆脱array_1:

Map::Map(int times){
    ptr=new int[5];  // or better define a constant to avoid hard coded sizes        
    for (int i=0;i<5;i++){
        ptr[i]=i*times;
    }
}

请注意,如果使用指针,则需要确保其上的常量。这意味着您还应该定义复制构造函数和赋值运算符(以避免ptr被盲目复制),以及析构函数(删除动态分配的数组)。

P.S。: 我想你正在学习C ++并且还不熟悉矢量。这些可以避免这里的所有麻烦

编辑: 如果您在任何对象被销毁之前遇到问题,那是因为dump()的执行情况不好:您将指针增加到其中,这样它就不再指向数组的开头了。

void Map::dump(){
    for (int i=0;i<5;i++){
        cout<<ptr[i]<<endl;  // don't change ptr value !! 
    }
}

避免此类问题的一个简单技巧是系统地声明不应该将对象状态更改为const的成员函数:

class Map {
   ...
   void dump() const;
   ...
}

如果您尝试意外更改成员,则编译器会发出错误。

答案 1 :(得分:0)

以下代码运行良好:

#include <stdio.h>
#include <iostream>
#include <conio.h>
using namespace std; 
class Map
{
public:
    Map(int times);         // Create an empty map (i.e., one with no key/value pairs)
    int size();    // Return the number of key/value pairs in the map.
    void dump();
    void swap(int &other);
    int *retrieve();
    void setptr(int *newptr);
private:
    int *ptr;
    int array_1[5];
};


Map::Map(int times){
    for (int i=0;i<5;i++){
        array_1[i]=i*times;
    }
    ptr=array_1;
}

void Map::dump(){
    for (int i=0;i<5;i++)
    {
        cout<<ptr[i]<<endl;        
    }

}

void Map::swap(int &other){
    int *temp;
    temp=this->ptr;
    this->ptr=&other;
    other = *temp;
}

int *Map::retrieve(){
    return ptr;
}

void Map::setptr(int *newptr){
    ptr=newptr;
}

int main()
{
    Map m(2);
    Map n(3);
    m.dump();
    m.swap(*n.retrieve());
    m.dump();
    getchar();
}

1)增加了主要功能
2)更改了交换功能 但克里斯托弗指出的问题仍然存在,即指针将指向另一个对象中的数组。

编辑:你可能需要这样的东西:

void Map::swap(Map &other){
    Map *temp;
    temp=this;
    *this = other;
    other = *temp;
}

Map *Map::retrieve(){
    return this;
}

注意:它可能不优雅。