سؤال

وبقدر ما أستطيع أن أقول، وليس هناك سبب لا ينبغي أن يسمح لي لتمرير إشارة إلى مؤشر في C ++. ومع ذلك، محاولاتي للقيام بذلك فشلت، وليس لدي أي فكرة عن السبب.

وهذا هو ما أفعله:

void myfunc(string*& val)
{
    // Do stuff to the string pointer
}

// sometime later 
{
    // ...
    string s;
    myfunc(&s);
    // ...
}

وأنا الحصول على هذا الخطأ:

<اقتباس فقرة>   

لا يمكن تحويل المعلمة 1 من 'الأمراض المنقولة جنسيا :: سلسلة *' إلى 'الأمراض المنقولة جنسيا :: سلسلة * &'

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

المحلول

وظيفة الخاص بك تتوقع إشارة إلى مؤشر سلسلة الفعلي في مجال الدعوة، وليس مؤشر سلسلة مجهول. وهكذا:

string s;
string* _s = &s;
myfunc(_s);

ويجب تجميع ما يرام.

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

نصائح أخرى

والمشكلة هي أن تحاول ربط مؤقت إلى المرجع، الذي لا يسمح C ++ إلا إذا كانت الإشارة const.

وهكذا يمكنك القيام به واحد إما ما يلي:

void myfunc(string*& val)
{
    // Do stuff to the string pointer
}


void myfunc2(string* const& val)
{
    // Do stuff to the string pointer
}

int main()
// sometime later 
{
    // ...
    string s;
    string* ps = &s;

    myfunc( ps);   // OK because ps is not a temporary
    myfunc2( &s);  // OK because the parameter is a const&
    // ...

    return 0;
}

وتغييره إلى:

  std::string s;
  std::string* pS = &s;
  myfunc(pS);

وتحرير:

وهذا ما يسمى ref-to-pointer وأنت لا يمكن أن تمر عنوان مؤقت كمرجع للعمل. (إلا اذا كان const reference).

ورغم ذلك، لقد أظهرت std::string* pS = &s; (مؤشر إلى متغير محلي)، فإن استخدامه النموذجية على النحو التالي: عندما تريد المستدعى لتغيير مؤشر نفسها، وليس الكائن الذي يشير. على سبيل المثال، وهي وظيفة يخصص الذاكرة ويعين عنوان كتلة الذاكرة التي خصصت لحجتها يجب أن تأخذ في إشارة إلى مؤشر أو مؤشر إلى مؤشر:

void myfunc(string*& val)
{
//val is valid even after function call
   val = new std::string("Test");

}

و&s تنتج مؤشر مؤقت لسلسلة وأنت لا تستطيع أن تشير إلى كائن مؤقت.

وجرب:

void myfunc(string& val)
{
    // Do stuff to the string pointer
}

// sometime later 
{
    // ...
    string s;
    myfunc(s);
    // ...
}

أو

void myfunc(string* val)
{
    // Do stuff to the string pointer
}

// sometime later 
{
    // ...
    string s;
    myfunc(&s);
    // ...
}

وتحرير: أنا جربت بعض، واكتشفت شيء ودهاء قليلا مما كنت اعتقد. وهنا ما أعتقد الآن هو الجواب دقيقة.

و&s ليست lvalue بحيث لا يمكنك إنشاء مرجع له إلا نوع من الإشارة هو الإشارة إلى const. هكذا على سبيل المثال، لا يمكنك أن تفعل

string * &r = &s;

ولكن يمكنك أن تفعل

string * const &r = &s;

إذا كنت وضعت إعلانا مماثلا في رأس وظيفة، وأنها ستعمل.

void myfunc(string * const &a) { ... }

وهناك مسألة أخرى، وهي المؤقتة المتقبلة. والقاعدة هي أنه يمكنك الحصول على مرجع إلى مؤقتة إلا إذا كان const. حتى في هذه الحالة يمكن للمرء أن يجادل بأن والصورة هي مؤقتة، وهكذا يجب أن يعلن const في تعريف الدالة. من الناحية العملية فإنه لا فرق في هذه الحالة. (انها إما rvalue أو كلتا الحالتين مؤقتة، وتنطبق نفس القاعدة). ومع ذلك، بالمعنى الدقيق للكلمة، وأعتقد أنها ليست مؤقتة وإنما هو rvalue. وأتساءل عما إذا كان هناك طريقة للتمييز بين الاثنين. (ربما يتم تعريفه ببساطة أن كل المؤقتة المتقبلة هي rvalues، وجميع غير lvalues-هي المؤقتة المتقبلة. أنا لست خبيرا في هذا المعيار.)

وأن يقال، المشكلة هي على الأرجح على مستوى أعلى. لماذا كنت ترغب في إشارة إلى عنوان s؟ إذا كنت ترغب في إشارة إلى مؤشر إلى s، تحتاج إلى تعريف مؤشر كما في

string *p = &s;
myfunc(p);

إذا كنت ترغب في إشارة إلى s أو مؤشر إلى s، تفعل الشيء مباشرة.

ولقد أدلى به للتو استخدام إشارة إلى مؤشر لجعل كل المؤشرات في شجرة ثنائية حذف باستثناء الجذر آمن. لجعل مؤشر آمنة لدينا فقط لتعيين إلى 0. I لا يمكن أن تجعل وظيفة يقوم بحذف شجرة (حفظ فقط الجذر) لقبول المرجع إلى مؤشر منذ أستخدمه الجذر (هذا المؤشر) كأول مساهمة في اجتياز اليسار واليمين.

void BinTree::safe_tree(BinTree * &vertex ) {
    if ( vertex!=0 ) {  // base case
        safe_tree(vertex->left);    // left subtree.
            safe_tree(vertex->right);   //  right subtree.
          // delete vertex;  // using this delete causes an error, since they were deleted on the fly using inorder_LVR. If inorder_LVR does not perform delete to the nodes, then, use delete vertex;
        vertex=0;  // making a safe pointer
    }
} // end in

وخلاصة القول، في إشارة إلى مؤشر غير صالح عندما معلمة رسمية هي (هذه) المؤشر.

ومرحبا بكم في C ++ 11 و rvalue المراجع:

#include <cassert>
#include <string>

using std::string;

void myfunc(string*&& val)
{
    assert(&val);
    assert(val);
    assert(val->c_str());
    // Do stuff to the string pointer
}

// sometime later 
int main () {
    // ...
    string s;
    myfunc(&s);
    // ...
}

والآن لديك حق الوصول إلى قيمة المؤشر (التي أشار إليها val)، والذي هو عنوان السلسلة.

ويمكنك تعديل المؤشر، وسوف يهتم أحد. وهذا هو جانب واحد من ما هو rvalue في المقام الأول.

كن حذرا: قيمة المؤشر صالحة فقط حتى يعود myfunc(). في الماضي، أعمالها مؤقتا.

وأنا أعلم أنه من POSIBLE لتمرير إشارات من المؤشرات، أنا فعلت هذا في الأسبوع الماضي، ولكن لا أستطيع أن أتذكر ما كان لغوي، كما يبدو التعليمات البرمجية الصحيح إلى ذهني الآن. ومع ذلك هناك خيار آخر هو استخدام مؤشرات من المؤشرات:

Myfunc(String** s)

وmyfunc ( "سلسلة * & فال") هذا في حد ذاته لا يجعل من أي معنى. "سلسلة * & فال" يعني "سلسلة فال"، * وويلغي كل منهما الآخر. وأخيرا يمكن للمرء أن لا با متغير السلسلة إلى وظيفة ( "سلسلة فال"). يمكن أن تنتقل أنواع البيانات الأساسية فقط إلى وظيفة، لأنواع البيانات الأخرى تحتاج إلى تمرير كما المؤشر أو مرجع. هل يمكن أن يكون إما سلسلة وفال أو سلسلة * فال إلى وظيفة.

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