C类设计 – 轻松初始化/构建对象

前端之家收集整理的这篇文章主要介绍了C类设计 – 轻松初始化/构建对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用C我构建了一个具有许多setter函数的Class,以及在运行时可以连续调用的各种函数.
所以我最终得到的代码如下:
A* a = new A();
a->setA();
a->setB();
a->setC();
...
a->doA();
a->doB();

不是,这很糟糕,但我不喜欢输入“a->”一遍又一遍地.
所以我重写了我的类定义,如下所示:

class A{
public:
    A();
    virtual ~A();

    A* setA();
    A* setB();
    A* setC();
    A* doA();
    A* doB();

    // other functions

private:

    // vars
};

那么我可以像我一样初始化我的课程:(方法1)

A* a = new A();
a->setA()->setB()->setC();
...
a->doA()->doB();

(我更喜欢,因为它更容易写)
为了更精确地实现这一点,你可以看到我在http://ken-soft.com/?p=234写的SDL Sprite C Class

一切似乎都很好.但是,我对这种方法的任何反馈感兴趣.
我注意到一个问题.如果我初始化我的班级:(方法2)

A a = A();
a.setA()->setB()->setC();
...
a.doA()->doB();

然后我有各种内存问题,有时事情不能正常工作(你可以通过改变我在Sprite Demo的main.cpp中初始化所有Sprite对象的方式来看到这一点).
这是正常的吗?或者行为应该是一样的吗?
编辑setter主要是为了让我的生活更容易初始化.我的主要问题是方法1和方法2对我来说有什么不同?

编辑:这是一个getter和setter示例:

Sprite* Sprite::setSpeed(int i) {
    speed = i;
    return this;
}

int Sprite::getSpeed() {
    return speed;
}

解决方法

与您的问题无关的一个注释,声明A a = A();可能没有做你期望的事情.在C中,对象不是默认为null的引用类型,因此该语句几乎永远不正确.你可能只想要A a;

A创建A的新实例,但是= A()部分调用A的复制构造函数,并使用临时默认构造A.如果你只做了A a;它会使用默认构造函数创建一个新的A实例.

如果没有为类显式实现自己的复制构造函数,编译器将为您创建一个.编译器创建的复制构造函数只会制作另一个对象数据的副本;这意味着如果你有任何指针,它将不会复制指向的数据.

所以,基本上,该行正在创建A的新实例,然后使用默认构造函数构造另一个临时A实例,然后将临时A复制到新A,然后破坏临时A.如果临时A正在获取资源它是构造函数并在它的析构函数中取消分配它们,您可能遇到问题,您的对象试图使用已经解除分配的数据,这是未定义的行为.

以此代码为例:

struct A {
    A() { 
        myData = new int;
        std::cout << "Allocated int at " << myData << std::endl;
    }
    ~A() { 
        delete myData; 
        std::cout << "Deallocated int at " << myData << std::endl;
    }
    int* myData;
};

A a = A();
cout << "a.myData points to " << a.myData << std::endl;

输出看起来像:

Allocated int at 0x9FB7128
Deallocated int at 0x9FB7128
a.myData points to 0x9FB7128

如您所见,a.myData指向已解除分配的地址.如果您尝试使用它指向的数据,您可能正在访问完全无效的数据,甚至是访问它的其他对象的数据.然后,一旦你的范围超出范围,它将尝试再次删除数据,这将导致更多问题.

猜你在找的C&C++相关文章