再次初始化变量

时间:2010-06-01 06:49:14

标签: c++ oop class

这听起来有点令人困惑。基本上,我有一个功能

CCard newCard() 
{
    /* Used to store the string variables intermittantly */
    std::stringstream ssPIN, ssBN;
    int picker1, picker2;
    int pin, bankNum;

    /* Choose 5 random variables, store them in stream */
    for( int loop = 0; loop < 5; ++loop )
    {
        picker1 = rand() % 8 + 1;
        picker2 = rand() % 8 + 1;
        ssPIN << picker1;
        ssBN  << picker2;
    }
    /* Convert them */
    ssPIN >> pin;
    ssBN  >> bankNum;

    CCard card( pin, bankNum );
    return card;
}

创建一个新的CCard变量并将其返回给调用者

CCard card = newCard();

我的老师告诉我,这样做违反了OOP原则,必须放在课堂上。他让我用这个方法作为构造函数。我做了什么:

CCard::CCard()
{
    m_Sperre   = false;
    m_Guthaben = rand() % 1000;

    /* Work */

    /* Convert them */
    ssPIN >> m_Geheimzahl;
    ssBN  >> m_Nummer;
}   

m_的所有变量都是成员变量。但是,当我正常初始化卡时,构造函数会起作用

CCard card();

在计划开始时。但是,我也有一个功能,应该创建一个新卡并将其返回给用户,此功能现在已经破坏。

原始命令:card = newCard();不再可用,card = new CCard();不起作用。我还有其他选择吗?我有一种感觉,使用构造函数将无法正常工作,我可能应该只创建一个类方法newCard,但我想看看它是否以某种方式按照老师想要的方式完成。

这给我带来了很多麻烦。我告诉老师,这是一个愚蠢的想法,并不是所有东西都必须归入OOP。从那时起他就告诉我Java或C#不允许在类之外的代码,这听起来有点不可思议。不确定您是否可以在C ++中执行此操作,尤其是在存在模板化函数或通用算法时。如果我没有强迫它进入类中,这对于C ++中的OOP来说是不是很糟糕?

修改

我要感谢大家的有用答案!但是,我相信我对这个问题的措辞有些搞砸,我认为人们不明白我在寻找什么。

想要初始化CCard类型的另一个成员。我想要初始化

CCard card一次,然后通过构造函数给出card个新值,因为这是老师告诉我要做的。我不想创建一个新的CCard对象,只需再次使用带有新值的相同变量。

这就是为什么我说它可能不适用于构造函数。所以我有一个函数应该采用初始化变量card,然后再次调用构造函数(“什么?”是我告诉老师的那个),然后给它新的值。

示例代码:

void foo()
{
    /* Initialize card with constructor */
    CCard card;
    /* Give it new values through the constructor AGAIN... */
    card;
}

这是实际问题。我很抱歉,如果我把每个人都弄糊涂了xD

4 个答案:

答案 0 :(得分:7)

只是一些基本的指示,因为你有一些误解。

这不会初始化CCard对象。它声明card是一个返回CCard且不带参数的函数。

CCard card();

如果你想构建一个CCard对象,那么就这样做。

CCard card;

您的构造函数将被调用,card应该正确初始化。

表达式new CCard()动态创建一个CCard对象并“返回”指针CCard对象,然后您需要delete }。在您成功创建并首先理解使用本地对象之前,我不建议使用它。

编辑以回复问题编辑

构造函数只能在对象的生命周期中调用一次,因此您无法“重新构造”对象。但是,如果您的类是可分配的,则通常可以为其分配默认构造临时值:

card = CCard();

答案 1 :(得分:3)

CCard card;

是使用默认构造函数的方法。

但你的老师错了,在C ++中我们会使用自由函数来非常频繁地扩展功能。

在你的情况下,使用构造函数是明智的,因为它是这样的,除非你有特殊需要,你不需要做一个newCard:这会生成不必要的副本。


“new”是为指针保留的,所以你必须使用这样的东西:

 CCard * card = new CCard();

你必须明确delete他们。但是只有在必要时才应该使用指针,如果可能的话,不应该使用'raw'而是聪明。 (参见boost :: shared_ptr等智能指针)


为您的编辑

您可以使用以下方式为您的CCard提供新值:

- )一种CCard方法,如:

card.newValues();

构造函数也可以调用“newValues()”以避免冗余。

- )一个以CCard作为参考参数的自由函数(或另一个类的成员):

 void newValues( CCard & card ) { /* set new values */ };

 newValues( card );

- )直接

 card.set( /*values*/ );

也许有一组访问器(set / get),如果它对你来说意味着什么。

您必须问自己的问题是,您是想要使用访问者更改类内部,还是只想在类中更改其值。

- )如果你真的想再次调用构造函数,可以复制一下:

 CCard c;
 c = CCard();

但这就像创建一个新的CCard一样。

答案 2 :(得分:1)

我也是C ++的新手,但我认为您可能需要一个复制构造函数来从函数中返回对象:

CCard::CCard (const CCard &rhs)
    : m_Gehiemzahl(rhs.m_Geheimzahl) // and so on for each member variable
{
}

不要忘记将原型添加到您的类声明中。

答案 3 :(得分:0)

老师试图做的一点是你不需要新的物品。相反,您需要提供一种与当前对象交互/操纵对象的方法。您不需要重建对象,只需更改对象的内部状态。

当然,对于“功能语言原则”有一个很大的转变,其中可变状态被认为是错误的重要来源。但可变状态本身并不坏;事实上,在对象的内部状态中进行更改并不总是显而易见的。你想让它显而易见。