سؤال

#include<iostream>
class name
{
public:
    int a;
    name():a(0){};
};
void add(name * pname)
{
    pname = NULL;
}
int main()
{
    name varName();
    name * pName = new name();
    add(pName);
    add(&varName);//error C2664: 'add' : cannot convert parameter 1 from 'name __cdecl *)(void)' to 'name *'
}
هل كانت مفيدة؟

المحلول

وأعتقد أنه يستحق أقول لك حول مشكلة مشابهة، أن يتسبب أيضا في ورطة:

struct foo { };
struct bar { bar(foo f); };

int main() {
  // does *not* create a bar object initialized by a default constructed 
  // foo object.
  bar b(foo());
}

ما هو ب حقا هي وظيفة يقوم بإرجاع bar ويأخذ كما الوسيطة الأولى مؤشر إلى وظيفة يقوم بإرجاع فو اتخاذ أي حجج. هو نفسه على النحو التالي:

bar b(foo(*)());

إذا كنت ترغب في إنشاء كائن شريط تهيئة من قبل فو الافتراضية التي شيدت، وضع أقواس حول الوسيطة. وهذا يجعل من لا تبدو وكأنها إعلان وظيفة بعد الآن، وسوف مترجم تفسير وكأنك تريد:

bar b((foo()));

وهناك أيضا حالات غير واضحة حيث يجب ارتفعت خطأ المترجم. يحصل دول مجلس التعاون الخليجي هذا خطأ، ولكن كومو يحصل على ذلك الحق مرة أخرى. النظر في المقتطف التالي

struct foo {
  static bool const value = false;
};

int main() {
  int v(int(foo::value));
}

وأنت من المحتمل أن نتوقع أن يأخذ هذا ثابت ثابت، ويلقي لint، تهيئة المتغير v إلى 0؟ لا، فإنه ليس وفقا لمعيار، لأن مهيئ يمكن أن تفسر على أنها إعلان، وفقا لتحليل تركيب النقي، كما يظهر التالي

struct foo {
  static int value;
};

// valid, parentheses are redundant! Defines `foo::value`.
int (foo::value); 

ومتى يمكن تفسير مهيئ بمثابة إعلان، في مثل هذه الحالة ككل إعلان سوف نعلن وظيفة. لذا، فإن خط في main يعلن وظيفة كما يلي، وحذف الأقواس زائدة ومعنى

int v(int foo::value);

وهذا سوف يؤدي إلى خطأ المترجم عند تحليل تعريف الدالة، لأنه قد لا يكون مؤهلا اسم وظيفة معلمة.

نصائح أخرى

الخطأ هو في السطر الأول من وظيفة الرئيسية:

name varName();

أنت لا إنشاء مثيل فئة اسم مع منشئ افتراضي, كنت في الواقع إعلان وظيفة جديدة تسمى varName, مع عدم وجود معلمات ، والتي ترجع اسم سبيل المثال.

يجب عليك بدلا من الكتابة:

name varName;

وكما انه من الجدير بالذكر أن الإضافة الخاصة بك وظيفة () ليس لديها أي آثار دائمة - كل ما يفعل وتحديد قيمة pname، الذي هو نسخة من مؤشر الذي يمر فيه. إذا كنت تريد أن يكون في الواقع أن عصا المهمة، سوف تحتاج إلى تمرير مؤشر بالرجوع ب "اسم * & pname".

name varName();

ويتم تفسير بمثابة إعلان وظيفة المحلي. استدعاء منشئ افتراضي، استخدم

name varName;

وبدلا من ذلك. الأكثر إرباكا، نعم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top