سؤال

ما هو بناء الجملة لتخصيص كائن ديناميكيًا باستخدام مُنشئ محمّل بشكل زائد في C++؟

إذا كان لدي فئة Foo:

class Foo{
public:
    Foo(string str, int nbr);    // Overloaded constructor
};

وفئة ثانية Foo2 (باستخدام Foo):

#include "Foo"
class Foo2{
public:
    Foo* myFoo;    // Wrong!
    Foo2(){
        myFoo = new Foo(myStr, myNbr);
    }
};

الخطأ المعروض هو التالي:

لا توجد وظيفة مطابقة لاستدعاء "Foo::Foo()"

كيف يمكنني، عند إنشاء مؤشر كائن myFoo، تحديد أنه سيستخدم ملف Foo(string str, int nbr) منشئ، لا Foo() البناء.

هل من الممكن دون استخدام تفويض المنشئ؟

هل كانت مفيدة؟

المحلول

بناء الجملة الخاص بك لإنشاء الكائن صحيح.

من الصعب الجزم بما أنك لم تخبر بالخطأ، ولكن أعتقد أن مشكلتك تكمن في أن المنشئ خاص.هذا يعني أنه لا يمكنك استخدام المُنشئ خارج الفصل.

تحرير بخصوص رسالة الخطأ:

إليك مثال كامل يتم تجميعه.لقد أضفت بعض الأمثلة على الأسطر التي قد تنتج الخطأ:لا توجد وظيفة مطابقة للاتصال بـ 'Foo::Foo()'.

#include <string>

class Foo{
public:
    Foo(std::string str, int nbr);
};

// empty definition
Foo::Foo(std::string str, int nbr) {}

// delegating constructor (c++11 feature)
// this would produce error: no matching function for call to 'Foo::Foo()'
//Foo::Foo(std::string str, int nbr) : Foo::Foo() {}

int main() {
    Foo* myFoo;
    myFoo = new Foo("testString", -1); // this is correct
    // trying to construct with default constructor
    //Foo myFoo2; // this would produce error: no matching function for call to 'Foo::Foo()'
    //Foo* myFoo3 = new Foo(); // so would this
}

نظرًا للخطأ، فإن الكود الخاص بك يحاول استخدام المُنشئ الافتراضي مكان ما.

تحرير 2 بخصوص الجديد الخاص بك Foo2 مثال.لا يزال إعلانك عن Foo* واستدعاء المنشئ صحيحًا ويجب تجميع التعليمات البرمجية إذا قمت بإصلاح رؤية الطريقة والفواصل المنقوطة المفقودة.المثال التالي يجمع:

#include <string>

class Foo{
public:
    Foo(std::string str, int nbr);    // Overloaded constructor
};

Foo::Foo(std::string str, int nbr){}

class Foo2{
    Foo* myFoo;    // This is still correct
public:
    Foo2() {
        myFoo = new Foo("", 1);
    }
};

int main() {
    Foo2 foo2;
}

نصائح أخرى

بناء الجملة صحيح.هناك العديد من الاحتمالات لأنك لم تكتب تعريفًا كاملاً للفئة.1.تحقق مما إذا كان يتم كتابة cnstsructor الافتراضي.2.تحقق مما إذا كان كلا المنشئين موجودين داخل القسم العام.3.بدلا من ذلك يمكنك تغيير استدعاء المنشئ على النحو التالي،

Foo* myFoo = new Foo("testString", -1);

يجب أن تعمل التعليمات البرمجية التالية.

class Foo
{

string str;
int num;
public:
    Foo(string p_str, int nbr):str(p_str),num(nbr){};    // Overloaded constructor
    Foo() {};    // Default constructor
};

الطريقة الصحيحة هي تهيئة الأعضاء في كل منشئ.يمكنك استخراج الكود المشترك الخاص بهم في وظيفة عضو init() خاصة واستدعائه في كل مُنشئ كما يلي:

class Foo {
    public:
        Foo(string x);
        Foo(string x, int y);
        ...
    private:
        void init(string x, int y);
};

Foo::Foo(string x)
{
    init(x, int(x) + 3);
    ...
}

Foo::Foo(string x, int y)
{
    init(x, y);
    ...
}

void Foo::init(string x, int y)
{
    ...
} 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top