这听起来有点令人困惑。基本上,我有一个功能
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
答案 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)
老师试图做的一点是你不需要新的物品。相反,您需要提供一种与当前对象交互/操纵对象的方法。您不需要重建对象,只需更改对象的内部状态。
当然,对于“功能语言原则”有一个很大的转变,其中可变状态被认为是错误的重要来源。但可变状态本身并不坏;事实上,在对象的内部状态中进行更改并不总是显而易见的。你想让它显而易见。