注册 登录
编程论坛 C++教室

代码出错了,能运行但是最后跳出个警告

黄昏乐章 发布于 2015-07-23 17:06, 917 次点击
程序代码:
#include<iostream>
#include<cassert>
using namespace std;
class point{
public:
    point(int xx = 0, int yy = 0)
    {
        x = xx;
        y = yy;

    }
    point(point &a);
    int getX(){
        return x;
    }
    int getY()
    {
        return y;

    }
    void move(int newX, int newY){
        x = newX;
        y = newY;
        cout << getX() << "," << getY() << endl;
    }
private:
    int x, y;
};
class arrayofpoints{
public:
    arrayofpoints(int size) : sizes(size){
        points = new point[size];
    }
    ~arrayofpoints(){
        cout << "deleteing..." << endl;
        delete[] points;
    }
    point& element(){

        return *(points++);//一改这里能运行但是最后说了句debug assertion failed! 我输入了3或者4
    }
private:
    point *points;
    int sizes;
};
int main()
{
    int count;
    cout << "please enter the count of points: ";
    cin >> count;
    arrayofpoints Points(count);
   
    Points.element().move(12, 56);
    Points.element().move(5, 0);
    return 0;
}

在书里扒了了代码自己改改
9 回复
#2
黄昏乐章2015-07-23 17:15
求大神指点
#3
黄昏乐章2015-07-23 17:16
我个人认为是指针溢出但是不应该啊
#4
yangfrancis2015-07-23 17:22
回复 楼主 黄昏乐章
Points.element().move(12, 56);
Points.element().move(5, 0);
这两步是不是需要把Points.element()用括号关起来,先得到point返回值,才能访问move成员函数?我猜的。
#5
黄昏乐章2015-07-23 17:57
回复 4楼 yangfrancis
正常编译,但是运行结束时出现wenti
#6
rjsp2015-07-23 20:30
element修改了points的值,析构时当然出错啦

    point& element( size_t index ) {
        return points[index];
    }
    point& element( size_t index ) const {
        return points[index];
    }

你的错误多着呐,基本上算是学歪了(我怀疑是一个javar教你的),尤其是第二个类缺少拷贝构造和赋值函数。
#7
醒山2015-07-23 21:34
我感觉也是,你写的更像是一个用JAVA在写c++,看起来好不舒服
#8
诸葛欧阳2015-07-23 21:40
第一个拷贝构造函数没写呀
#9
rjsp2015-07-24 10:43
程序代码:
#include <iostream>
#include <stdexcept>
#include <cassert>

struct point
{
    int x, y;

    point() : x(0), y(0)
    {
    }
    point( int x, int y ) : x(x), y(y)
    {
    }
};

std::ostream& operator<<( std::ostream& os, const point& pt )
{
    return os << '(' << pt.x << ',' << pt.y << ')';
}

// 之所以不用  point( int x=0, int y=0 ) 是为了防止出现 Point pt(x) 这种残疾代码
// point(point &a) 应该是 point( const point& pt ),但缺省的拷贝构造本身就合乎要求,因此不需要写
// getX这种命名多丑呀?要么 getx 或 get_x 这种广泛使用的命名,要么 GetX 这种微软钟爱的命名
// ,但在这里都不需要,因为不符合C++的习俗(C++连“属性”概念都觉得丑,不肯加,何况你这种)
// 这里用struct,而不是class,以特出这个结构的数据特征。对于struct,习俗是将成员变量放在最前面
// move 函数是不需要的,因为可以用更优雅的 pt = point(x,y) 来修改逻辑值

class arrayofpoints
{
public:
    arrayofpoints( size_t size ) try : ptrs_(new point[size]), size_(size)
    {
    }
    catch( std::bad_alloc& ) {
        throw;
    }

    arrayofpoints( const arrayofpoints& ptrs ) try : ptrs_(new point[ptrs.size_]), size_(ptrs.size_)
    {
    }
    catch( std::bad_alloc& ) {
        throw;
    }

    arrayofpoints& operator=( const arrayofpoints& ptrs )
    {
        if( this != &ptrs )
        {
            delete[] ptrs_;

            try {
                ptrs_ = new point[ptrs.size_];
                size_ = ptrs.size_;
            }
            catch( std::bad_alloc& ) {
                throw;
            }
        }
        return *this;
    }

    ~arrayofpoints()
    {
        delete[] ptrs_;
    }

    point& operator[]( size_t off )
    {
        return ptrs_[off];
    }
    const point& operator[]( size_t off ) const
    {
        return ptrs_[off];
    }

    point& at( size_t off )
    {
        if( off >= size_ )
            throw std::out_of_range("out of range");
        return ptrs_[off];
    }
    const point& at( size_t off ) const
    {
        if( off >= size_ )
            throw std::out_of_range("out of range");
        return ptrs_[off];
    }

private:
    point* ptrs_;
    size_t size_;
};
// 数组长度的类型,在C/C++中是size_t,不是int,你要牢牢记住
// operator new是可能抛出异常的,构造函数等中异常必须先捕获再转抛
// 一般而言,必须自定义析构函数的,也一定必须自定义拷贝构造函数和赋值函数
// 记住成员函数后面没有const修饰的,和有const修饰的,是两个不同的函数
// operator[]中不检查数组越界,at函数中必须检查数组越界,这是规矩
// 对struct/class而言,非public成员,都应该在名字尾部加下划线,这是习俗(微软的习俗不是这样)

using namespace std;
// 不要在定义通用类或函数时引入名字空间std,否则别人使用你的类或函数时就被强制引入了std。

int main( void )
{
    arrayofpoints Points( 2 );
  

    Points[0] = point(12, 56);
    Points[1] = point(5, 0);

    cout << Points[0] << '\n'
         << Points[1] << std::endl;

    return 0;
}

// 其它更多的东西等你入门了再讲,
// 比如 arrayofpoints 这种容器类,应当实现 swap 功能,应当实现 迭代 功能
// 比如 C++14 中的“右值引用”,你得加入这样的构造函数
// 比如 既然你的是仿数组类,那么也应该做得跟数组的用法差不多。(这里面对编码要求比较高)
// ……
#10
flkj20152015-07-24 20:20
把element函数修改一下:
point& element(int index){
        return *(points+index);
    }
用index值来选择位置
保证 point *points的位置不要改变,不然最后析构的时候,会溢出。
1