ස්මාර්ට් පොයින්ටරයක් ​​යනු කුමක්ද සහ මා එය භාවිතා කළ යුත්තේ කවදාද?


1836

ස්මාර්ට් පොයින්ටරයක් ​​යනු කුමක්ද සහ මා එය භාවිතා කළ යුත්තේ කවදාද?



2
විෂුවල් ස්ටුඩියෝ 2005 හි std :: auto_ptr ක්‍රියාත්මක කිරීම දරුණු ලෙස බිඳී ඇති බව සලකන්න. <br> http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98871 <br> http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842 භාවිතා කරන්න ඒ වෙනුවට ඒවා වැඩි කරන්න.
රිචඩ්

25
මෙම විෂය පිළිබඳ විශිෂ්ට ලිපි දෙකක්: - ස්මාර්ට් පොයින්ටර්ස් - කුමක්ද, ඇයි, කුමන? - සතියේ ගුරු # 25
ලේසර්

1
විවිධ රසයන්ගෙන් යුත් ස්මාර්ට් පොයින්ටර්ස් නිර්මාණය කිරීමේ අශෝභනකම පිළිබඳ ඇලෙක්සැන්ඩ්‍රෙස්කුගේ (නිදහස්) පරිච්ඡේදය මෙන්න: infoit.com/articles/article.aspx?p=31529 ඔහු ක්‍රියාත්මක කිරීමේදී, ඔහුට අවශ්‍ය කුමන ගුණාංගද යන්න සඳහන් කිරීම සඳහා අච්චු තර්ක “ප්‍රතිපත්ති” ලෙස භාවිතා කරයි ( උදා: යොමු ගණන් කිරීම), සම්මත පුස්තකාලය වෙනම පන්ති භාවිතා කරයි. Std :: unique_ptr වැනි දෙයක් කිරීමට හැකි වන පරිදි අගයන් යොමු කිරීමට පෙර ඔහු ද ලියමින් සිටි බව සලකන්න.
ලෝහ

ඉහත ප්‍රශ්නයට තවත් එක් කරුණක් එක් කිරීමට මම කැමතියි, ස්මාර්ට් පොයින්ටර් std :: shared_ptr සතුව ග්‍රාහක ක්‍රියාකරු නොමැති අතර පොන්ටර් අංක ගණිතයට සහය නොදක්වයි, අපට ගොඩනංවන ලද දර්ශකයක් ලබා ගැනීමට get () භාවිතා කළ හැකිය.
suresh m

Answers:


1893

යාවත්කාලීන කරන්න

මෙම පිළිතුර තරමක් පැරණි වන අතර, ඒ අවස්ථාවේ දී 'හොඳ' දේ විස්තර කරයි, එය බූස්ට් පුස්තකාලය විසින් සපයන ලද ස්මාර්ට් පොයින්ටර් ය. C ++ 11 සිට, පුස්තකාලයක් ප්රමාණවත් ස්මාර්ට් සූචක වර්ග ලබා දී ඇත, ඔබ භාවිතය අනුග්රහය යුතු නිසා std::unique_ptr, std::shared_ptrසහ std::weak_ptr.

එසේම විය std::auto_ptr. එය පිටපත් කිරීමේ “විශේෂ” භයානක හැකියාවක් ද ඇති බව හැරෙන්නට, එය බොහෝ දුරට විෂය පථයට සමාන විය - එය අනපේක්ෂිත ලෙස හිමිකාරිත්වය මාරු කරයි.
එය C ++ 11 හි ඉවත් කර C ++ 17 හි ඉවත් කරන ලදි , එබැවින් ඔබ එය භාවිතා නොකළ යුතුය.

std::auto_ptr<MyObject> p1 (new MyObject());
std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership. 
                                 // p1 gets set to empty!
p2->DoSomething(); // Works.
p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.

පැරණි පිළිතුර

ස්මාර්ට් පොයින්ටරය යනු පෙන්වා ඇති වස්තුවෙහි ආයු කාලය කළමනාකරණය කිරීම සඳහා 'අමු' (හෝ 'හිස්') සී ++ දර්ශකයක් ඔතා ඇති පන්තියකි. තනි ස්මාර්ට් පොයින්ටර් වර්ගයක් නොමැත, නමුත් ඒ සියල්ලම ප්‍රායෝගික ආකාරයකින් අමු දර්ශකයක් වියුක්ත කිරීමට උත්සාහ කරයි.

අමු දර්ශකයන්ට වඩා ස්මාර්ට් පොයින්ටර්ස් වඩාත් කැමති විය යුතුය. ඔබට දර්ශකයන් භාවිතා කළ යුතු යැයි ඔබට හැඟේ නම් (මුලින්ම ඔබ සැබවින්ම එසේ කරන්නේ නම් සලකා බලන්න ), සාමාන්‍යයෙන් ඔබට ස්මාර්ට් පොයින්ටරයක් ​​භාවිතා කිරීමට අවශ්‍ය වනුයේ අමු දර්ශකයන් සමඟ ඇති බොහෝ ගැටලු සමනය කළ හැකි නිසාය.

අමු දර්ශකයන් සමඟ, ක්‍රමලේඛකයාට වස්තුව තවදුරටත් ප්‍රයෝජනවත් නොවන විට එය පැහැදිලිවම විනාශ කළ යුතුය.

// Need to create the object to achieve some goal
MyObject* ptr = new MyObject(); 
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?

සංසන්දනය කිරීමෙන් ස්මාර්ට් පොයින්ටරයක් ​​මඟින් වස්තුව විනාශ වන්නේ කවදාද යන්න පිළිබඳ ප්‍රතිපත්තියක් අර්ථ දක්වයි. ඔබ තවමත් වස්තුව නිර්මාණය කළ යුතුව ඇත, නමුත් එය විනාශ කිරීම ගැන ඔබට තවදුරටත් කරදර විය යුතු නැත.

SomeSmartPtr<MyObject> ptr(new MyObject());
ptr->DoSomething(); // Use the object in some way.

// Destruction of the object happens, depending 
// on the policy the smart pointer class uses.

// Destruction would happen even if DoSomething() 
// raises an exception

භාවිතා වන සරල ප්රතිපත්ති එවැනි විසින් ක්රියාත්මක ලෙස ස්මාර්ට් පහිටුම් දක්වනය දවටනය වස්තුව, විෂය පථය සම්බන්ධ boost::scoped_ptrහෝ std::unique_ptr.

void f()
{
    {
       std::unique_ptr<MyObject> ptr(new MyObject());
       ptr->DoSomethingUseful();
    } // ptr goes out of scope -- 
      // the MyObject is automatically destroyed.

    // ptr->Oops(); // Compile error: "ptr" not defined
                    // since it is no longer in scope.
}

බව කරුණාවෙන් std::unique_ptrඅවස්ථා පිටපත් කල නොහැක. මෙය දර්ශකය කිහිප වතාවක් මකා දැමීම වළක්වයි (වැරදියට). කෙසේ වෙතත්, ඔබට එය ඇමතීමේ වෙනත් කාර්යයන් වෙත යොමු කළ හැකිය.

std::unique_ptrඔබට යම් වස්තුවක ආයු කාලය නිශ්චිත කේත කොටසකට සම්බන්ධ කිරීමට අවශ්‍ය වූ විට s ප්‍රයෝජනවත් වේ, නැතහොත් ඔබ එය වෙනත් වස්තුවක් තුළ සාමාජික දත්ත ලෙස කාවැද්දුවහොත් එම වස්තුවේ ආයු කාලය. කේතයේ අඩංගු කොටස පිටවන තුරු හෝ අඩංගු වස්තුව විනාශ වන තුරු වස්තුව පවතී.

වඩාත් සංකීර්ණ ස්මාර්ට් පොයින්ටර් ප්‍රතිපත්තියක් මඟින් යොමු දර්ශකය ගණනය කිරීම ඇතුළත් වේ. මෙය දර්ශකය පිටපත් කිරීමට ඉඩ දෙයි. වස්තුව පිළිබඳ අවසාන "යොමුව" විනාශ වූ විට, වස්තුව මකා දමනු ලැබේ. මෙම ප්‍රතිපත්තිය ක්‍රියාත්මක වන්නේ boost::shared_ptrසහ std::shared_ptr.

void f()
{
    typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias
    MyObjectPtr p1; // Empty

    {
        MyObjectPtr p2(new MyObject());
        // There is now one "reference" to the created object
        p1 = p2; // Copy the pointer.
        // There are now two references to the object.
    } // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero. 
  // The object is deleted.

ඔබේ වස්තුවේ ආයු කාලය වඩාත් සංකීර්ණ වන විට යොමු ගණනය කළ දර්ශක ඉතා ප්‍රයෝජනවත් වන අතර එය කේතයේ යම් කොටසකට හෝ වෙනත් වස්තුවකට කෙලින්ම සම්බන්ධ නොවේ.

යොමු කරන ලද දර්ශකයන්ට යොමු දැක්වීමේ එක් අඩුපාඩුවක් තිබේ - භයානක යොමු කිරීමක් නිර්මාණය කිරීමේ හැකියාව:

// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!

තවත් හැකියාවක් වන්නේ චක්‍රලේඛ යොමු කිරීම:

struct Owner {
   std::shared_ptr<Owner> other;
};

std::shared_ptr<Owner> p1 (new Owner());
std::shared_ptr<Owner> p2 (new Owner());
p1->other = p2; // p1 references p2
p2->other = p1; // p2 references p1

// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!

මෙම ගැටළුව විසඳීම සඳහා, බූස්ට් සහ සී ++ 11 යන දෙකම weak_ptra සඳහා දුර්වල (ගණනය නොකළ) යොමු කිරීමක් අර්ථ දැක්වීමට a අර්ථ දක්වා ඇත shared_ptr.


7
std::auto_ptr<MyObject> p1 (new MyObject());ඒ වෙනුවට ඔබ අදහස් කළේ std::auto_ptr<MyObject> p1 (new Owner());?
මාටීන් උල්හාක්

35
නියම පිළිතුර. එය c ++ 11 සඳහා යාවත්කාලීන කළේ නම් හොඳයි. නව 11 ප්‍රමිතිය පිළිබඳ තොරතුරු සොයමින් මෙම පිළිතුර මට හමු වූ අතර අනාගත අමුත්තන්ට යාවත්කාලීන තොරතුරු සොයා ගත හැකි නම් හොඳයි. මම දන්නවා auto_ptr අතහැර දමා ඇති බව. විස්තර කර ඇති පරිදි shated_ptr සහ දුර්වල_ptr පවතින බව මම විශ්වාස කරමි, සහ scoped_ptr දැන් ප්‍රමිතියේ අද්විතීය_ptr වේ. මෙය සත්‍ය නම්, කරුණාකර මෙම පිළිතුර යාවත්කාලීන කළ හැකිද?
සාවුල්බැක්

16
ගණනය කළ දර්ශකයන් යොමු කිරීම සඳහා අඩුපාඩුවක් යැයි කියනු ලැබේ. විය හැකි අනතුරු ඇඟවීම් ඕනෑම C ++ දර්ශකයක අඩුපාඩුවකි . ඇත්ත වශයෙන්ම, ස්මාර්ට් පොයින්ටර්ස් සමනය කිරීමට අදහස් කරන අඩුපාඩුව එයයි.
මයිකල් ඩෝර්ස්ට්

16
ඔබ ස්මාර්ට් පොයින්ටරයකට දර්ශකයක් ප්‍රකාශ කරන්නේ නම් (උදාහරණයේ දී කළ පරිදි) ඔබ දැනුවත්ව ස්මාර්ට් පොයින්ටරයේ සියලු ප්‍රතිලාභ අත්හරියි. මෙය අඩුපාඩුවක් හෝ නිර්මාණ දෝෂයක් නොවේ, එය සිතාගත හැකි වඩාත්ම මෝඩ භාවිතයයි.
මයිකල් ඩෝර්ස්ට්

3
const std::auto_ptrඔබ C ++ 03 සමඟ සිරවී ඇත්නම් A භාවිතා කිරීම ආරක්ෂිතයි. C ++ 11 වෙත ප්‍රවේශය ලැබෙන තෙක් මම එය pimpl රටාව සඳහා භාවිතා කළෙමි.
ටෝබි ස්පයිට්

306

නවීන C ++ (C ++ 11 සහ ඊට පසු) මේ දිනවල සරල පිළිතුරක් මෙන්න:

  • ස්මාර්ට් පොයින්ටරයක් ​​යනු කුමක්ද?
    එය දර්ශකයන් මෙන් භාවිතා කළ හැකි නමුත් ස්වයංක්‍රීය මතක කළමනාකරණයේ අතිරේක ලක්ෂණය සපයන වර්ගයකි: ස්මාර්ට් පොයින්ටරයක් ​​තවදුරටත් භාවිතයේ නොමැති විට, එය පෙන්වා දෙන මතකය අවලංගු වේ ( විකිපීඩියාවේ වඩාත් සවිස්තරාත්මක අර්ථ දැක්වීමද බලන්න ).
  • මම එකක් භාවිතා කළ යුත්තේ කවදාද?
    මතක කොටසක හිමිකාරිත්වය නිරීක්ෂණය කිරීම, වෙන් කිරීම හෝ වෙන් කිරීම ඇතුළත් කේතයේ; ස්මාර්ට් පොයින්ටරය බොහෝ විට මෙම දේවල් පැහැදිලිව කිරීමේ අවශ්‍යතාවය ඔබට ඉතිරි කරයි.
  • නමුත් කුමන අවස්ථාවන්හිදී මා භාවිතා කළ යුත්තේ කුමන ස්මාර්ට් පොයින්ටරයද?
    • std::unique_ptrඑකම වස්තුවට බහුවිධ යොමු දැක්වීමට ඔබ අදහස් නොකරන විට භාවිතා කරන්න . නිදසුනක් ලෙස, මතකයට දර්ශකයක් සඳහා එය භාවිතා කරන්න, එය යම් විෂය පථයකට ඇතුළු වූ විට සහ විෂය පථයෙන් පිටවීමෙන් වෙන් කරනු ලැබේ.
    • std::shared_ptrඔබට ඔබේ වස්තුව විවිධ ස්ථාන වලින් යොමු කිරීමට අවශ්‍ය වූ විට භාවිතා කරන්න - තවද මෙම යොමු කිරීම් සියල්ලම නැති වී යන තුරු ඔබේ වස්තුව වෙන් කිරීම අවශ්‍ය නොවේ.
    • std::weak_ptrඔබට විවිධ ස්ථාන වලින් ඔබේ වස්තුව යොමු කිරීමට අවශ්‍ය වූ විට භාවිතා කරන්න - එම යොමු කිරීම් නොසලකා හැරීම හා අවලංගු කිරීම සුදුසුය (එබැවින් ඔබ අවලංගු කිරීමට උත්සාහ කරන විට වස්තුව නැති වී ඇති බව ඔවුන් සටහන් කරනු ඇත).
    • boost::ස්මාර්ට් පොයින්ටර්ස් භාවිතා නොකරන්න හෝ std::auto_ptrඔබට අවශ්‍ය නම් ඔබට කියවිය හැකි විශේෂ අවස්ථා හැර.
  • හේයි, මම ඇහුවේ නැහැ මොන එක පාවිච්චි කරන්නද කියලා!
    අහ්, නමුත් ඔබට එය ඇත්ත වශයෙන්ම අවශ්‍ය විය, එය පිළිගන්න.
  • ඉතින් මම සාමාන්‍ය දර්ශකයන් භාවිතා කළ යුත්තේ කවදාද?
    බොහෝ විට මතක හිමිකාරිත්වය නොසලකා හරින කේතයක. මෙය සාමාන්‍යයෙන් වෙනත් ස්ථානයකින් දර්ශකයක් ලබා ගන්නා අතර ඒවා වෙන් කිරීම හෝ වෙන් කිරීම සිදු නොකරන අතර ඒවා ක්‍රියාත්මක කිරීම ඉක්මවා යන දර්ශකයේ පිටපතක් ගබඩා නොකරයි.

5
ස්මාර්ට් (හිමිකාරීත්ව) දර්ශකයන් නිසි මතක කළමනාකරණයට උපකාරී වන අතර, දත්ත ව්‍යුහයන්හි වෙනත් ආයතනික අරමුණු සඳහා අමු (හිමිකාරී නොවන) දර්ශක තවමත් ප්‍රයෝජනවත් බව සඳහන් කිරීම වටී. හර්බ් සූටර් විසින් CppCon 2016 හි දී මේ පිළිබඳව විශාල ඉදිරිපත් කිරීමක් ලබා දී ඇති අතර, එය ඔබට යූ ටියුබ් හි දැක ගත හැකිය: සී ++ හි කාන්දු-නිදහස ... පෙරනිමියෙන්.
wiktor.wandachowicz

1
@ wiktor.wandachowicz T*කිරීමට std::unique_ptr<T>කුමක් std::weak_ptr<T>ද කියලාstd::shared_ptr<T>
Caleth

Ale කැලෙත්: නැහැ, මම එහෙම කියන්නේ නැහැ.
einpoklum

1
Ony ටෝනි ටැනස්: ගෞරවයෙන් - එය ප්‍රධාන සංස්කරණයකි; වියුක්ත වන මගේ පිළිතුරට එය අවශ්‍ය යැයි මට හැඟෙන්නේ නැත. විවරණයක ඇති සබැඳිය මත උදාහරණය වෙනම පිළිතුරක් බවට පත් කිරීමට මම යෝජනා කරමි.
einpoklum

112

ස්මාර්ට් පොයින්ටරය යනු අමතර ක්‍රියාකාරීත්වයක් සහිත දර්ශක වැනි වර්ගයකි, උදා: ස්වයංක්‍රීය මතක විස්ථාපනය, යොමු ගණන් කිරීම යනාදිය.

කුඩා හැඳින්වීමක් ස්මාර්ට් පොයින්ටර්ස් පිටුවේ ඇත - කුමක්ද, ඇයි, කුමන? .

සරල ස්මාර්ට්-පොයින්ටර් වර්ගයක් වන්නේ std::auto_ptr(සී ++ ප්‍රමිතියේ 20.4.5 පරිච්ඡේදය), එය මතකය විෂය පථයෙන් බැහැර වූ විට ස්වයංක්‍රීයව විස්ථාපනය කිරීමට ඉඩ සලසයි.

තවත් පහසු වර්ගයක් වන්නේ boost::shared_ptrවස්තු පිළිබඳ කිසිදු සඳහනක් ඉතිරි නොවන විට යොමු ගණන් කිරීම ක්‍රියාත්මක කරන අතර ස්වයංක්‍රීයව මතකය අවලංගු කිරීමයි. මෙය මතක කාන්දු වීම වළක්වා ගැනීමට උපකාරී වන අතර RAII ක්‍රියාත්මක කිරීමට භාවිතා කිරීම පහසුය .

20 වන පරිච්ඡේදයේ ඩේවිඩ් වැන්ඩෙවෝර්ඩ්, නිකොලායි එම්. ජොසුටිස් විසින් රචිත "සී ++ ආකෘති: සම්පූර්ණ මාර්ගෝපදේශය" පොතේ විෂය ගැඹුරින් ආවරණය කර ඇත . ස්මාර්ට් පොයින්ටර්ස්. ආවරණය කරන ලද සමහර මාතෘකා:

  • ව්‍යතිරේකයන්ට එරෙහිව ආරක්ෂා කිරීම
  • දරන්නන්, (සටහන, std :: auto_ptr යනු එවැනි ස්මාර්ට් පොයින්ටරයක් ​​ක්‍රියාත්මක කිරීමයි)
  • සම්පත් අත්පත් කර ගැනීම ආරම්භ කිරීම (මෙය C ++ හි ව්‍යතිරේක-ආරක්ෂිත සම්පත් කළමනාකරණය සඳහා නිතර භාවිතා වේ)
  • දරන්නාගේ සීමාවන්
  • යොමු ගණන් කිරීම
  • සමගාමී කවුන්ටර ප්‍රවේශය
  • විනාශය සහ ඉවත් කිරීම

3
std::auto_ptrඔබට අහම්බෙන් හිමිකාරිත්වය පැවරිය හැකි බැවින් අවවාදය අවලංගු කර ඇති අතර එය අධෛර්යමත් කරයි. - C ++ 11 මඟින් Boost හි අවශ්‍යතාවය ඉවත් කරයි, භාවිතා කරන්න std::unique_ptr, std::shared_ptrසහstd::weak_ptr
ninMonkey

42

ක්‍රිස්, සර්ග්දෙව් සහ ලිලියෝඩ් විසින් සපයන ලද අර්ථ දැක්වීම් නිවැරදි ය. මගේ ජීවිතය සරල ලෙස තබා ගැනීම සඳහා මම වඩාත් සරල අර්ථ දැක්වීමකට කැමතියි: ස්මාර්ට් පොයින්ටරය යනු හුදෙක් -> සහ *ක්‍රියාකරුවන් අධික ලෙස පටවන පන්තියකි . ඔබේ වස්තුව ශබ්දාර්ථයෙන් අවධානය යොමුකළ වගේ එහෙත් ඔබ එය යොමු ඡන්ද ගණන් කිරීමේ ස්වයංක්රීය විනාශ ආදිය ඇතුළු මාර්ගය සිසිල් දේවල්, කරන්න පුළුවන් බව මාර්ගයෙන් shared_ptrහා auto_ptrබොහෝ අවස්ථාවලදී ප්රමාණවත් වේ, නමුත් කුඩා idiosyncrasies ඔවුන්ගේ මාලාවක් සමග එන්න.


30

ස්මාර්ට් පොයින්ටරයක් ​​යනු "චාර් *" වැනි සාමාන්‍ය (ටයිප් කළ) දර්ශකයක් වැනි ය, දර්ශකය විෂය පථයෙන් බැහැර වන විට හැර එය පෙන්වා දෙන දේ මකා දමනු ලැබේ. "->" භාවිතා කිරීමෙන් ඔබට සාමාන්‍ය දර්ශකයක් මෙන් එය භාවිතා කළ හැකිය, නමුත් ඔබට දත්ත වෙත සත්‍ය දර්ශකයක් අවශ්‍ය නම් නොවේ. ඒ සඳහා ඔබට "& * ptr" භාවිතා කළ හැකිය.

මෙය ප්‍රයෝජනවත් වේ:

  • අළුත් දේ සමඟ වෙන් කළ යුතු වස්තූන්, නමුත් එම තොගයේ ඇති දේට සමාන ජීවිත කාලයක් ලබා ගැනීමට ඔබ කැමති වේ. වස්තුව ස්මාර්ට් පොයින්ටරයකට පවරා ඇත්නම්, වැඩසටහන එම ශ්‍රිතයෙන් / වාරණයෙන් ඉවත් වූ විට ඒවා මකා දැමෙනු ඇත.

  • පංතිවල දත්ත සාමාජිකයන්, එම නිසා වස්තුව මකා දැමූ විට, සතු සියලු දත්ත මකා දමනු ලැබේ, ඩිස්ට්‍රැක්ටරයේ විශේෂ කේතයක් නොමැතිව (ඩිස්ට්‍රැක්ටරය අථත්‍ය බව ඔබට සහතික විය යුතුය, එය සෑම විටම පාහේ කළ යුතු හොඳ දෙයකි) .

පහත දැක්වෙන විට ඔබට ස්මාර්ට් පොයින්ටරයක් ​​භාවිතා කිරීමට අවශ්‍ය නොවනු ඇත :

  • ... දර්ශකය ඇත්ත වශයෙන්ම දත්ත අයිති කර නොගත යුතුය ... එනම්, ඔබ දත්ත භාවිතා කරන විට, නමුත් ඔබ එය යොමු කරන ශ්‍රිතයෙන් නොනැසී සිටීමට ඔබට අවශ්‍යය.
  • ... ස්මාර්ට් පොයින්ටරය කිසියම් අවස්ථාවක විනාශ නොවනු ඇත. එය කිසි විටෙකත් විනාශ නොවන මතකයේ රැඳී සිටීමට ඔබට අවශ්‍ය නැත (ගතිකව වෙන් කර ඇති නමුත් පැහැදිලිව මකා නොදමන වස්තුවක වැනි).
  • ... ස්මාර්ට් පොයින්ටර් දෙකක් එකම දත්ත වෙත යොමු විය හැකිය. (කෙසේ වෙතත්, එය හැසිරවිය හැකි වඩා හොඳ දර්ශකයන් ඇත ... එය යොමු ගණන් කිරීම ලෙස හැඳින්වේ .)

මෙයද බලන්න:


18

බොහෝ වර්ගවල ස්මාර්ට් පොයින්ටර්ස් මඟින් ඔබ වෙනුවෙන් දර්ශකය බැහැර කිරීම පාලනය කරයි. වස්තූන් අතින් බැහැර කිරීම ගැන තවදුරටත් සිතිය යුතු නැති නිසා එය ඉතා පහසුය.

බහුලව භාවිතා වන ස්මාර්ට් පොයින්ටර්ස් std::tr1::shared_ptr(හෝ boost::shared_ptr), සහ, අඩු වශයෙන් , std::auto_ptr. මම නිතිපතා භාවිතා කිරීම නිර්දේශ කරමි shared_ptr.

shared_ptrඉතා බහුකාර්ය වන අතර වස්තූන් “ඩීඑල්එල් මායිම් හරහා ගමන් කළ යුතු” අවස්ථා ද ඇතුළුව විවිධාකාර බැහැර කිරීමේ අවස්ථා සමඟ කටයුතු කරයි ( libcඔබේ කේතය සහ ඩීඑල්එල් අතර විවිධ ඒවා භාවිතා කරන්නේ නම් පොදු බියකරු අවස්ථාව ).


18

ස්මාර්ට් පොයින්ටරයක් ​​යනු දර්ශකයක් මෙන් ක්‍රියා කරන වස්තුවකි, නමුත් ඊට අමතරව ඉදිකිරීම්, විනාශය, පිටපත් කිරීම, චලනය කිරීම සහ අවලංගු කිරීම පාලනය කරයි.

කෙනෙකුට තමන්ගේම ස්මාර්ට් පොයින්ටරයක් ​​ක්‍රියාත්මක කළ හැකි නමුත් බොහෝ පුස්තකාලවල විවිධ වාසි සහ අවාසි සහිතව ස්මාර්ට් පොයින්ටර් ක්‍රියාත්මක කිරීම සපයයි.

උදාහරණයක් ලෙස, බූස්ට් පහත දැක්වෙන ස්මාර්ට් පොයින්ටර් ක්‍රියාත්මක කිරීම් සපයයි:

  • shared_ptr<T>Tවස්තුව තවදුරටත් අවශ්‍ය නොවන විට තීරණය කිරීම සඳහා යොමු ගණන් භාවිතා කිරීම සඳහා වන දර්ශකයකි .
  • scoped_ptr<T>දර්ශකයක් විෂය පථයෙන් බැහැර වූ විට ස්වයංක්‍රීයව මකා දමනු ලැබේ. පැවරුමක් කළ නොහැක.
  • intrusive_ptr<T>යනු තවත් යොමු ගණන් කිරීමේ ලක්ෂ්‍යයකි. එය වඩා හොඳ කාර්ය සාධනයක් සපයයි shared_ptr, නමුත් Tඑහි ම යොමු ගණන් කිරීමේ යාන්ත්‍රණයක් සැපයීමට වර්ගය අවශ්‍ය වේ .
  • weak_ptr<T>යනු දුර්වල දර්ශකයක් වන අතර shared_ptrඑය රවුම් යොමු කිරීම් වලක්වා ගැනීම සඳහා ක්‍රියා කරයි.
  • shared_array<T>වැනි shared_ptr, නමුත් අරා සඳහා T.
  • scoped_array<T>වැනි scoped_ptr, නමුත් අරා සඳහා T.

මේවා එක් එක් රේඛීය විස්තරයක් පමණක් වන අතර අවශ්‍යතාවය අනුව භාවිතා කළ හැකිය, වැඩි විස්තර සහ උදාහරණ සඳහා කෙනෙකුට බූස්ට් හි ලේඛනගත කිරීම දෙස බැලිය හැකිය.

මීට අමතරව, සී ++ සම්මත පුස්තකාලය ස්මාර්ට් පොයින්ටර් තුනක් සපයයි; std::unique_ptrඅද්විතීය හිමිකාරිත්වය std::shared_ptrසඳහා, හවුල් හිමිකම සඳහා සහ std::weak_ptr. std::auto_ptrC ++ 03 හි පැවතුන නමුත් දැන් එය ඉවත් කර ඇත.


scoped_ptrදේශීයව ප්‍රකාශයට පත් නොවන්නේ මන්දැයි කරුණාකර පැහැදිලි කරන්න const unique_ptr- එය විෂය පථයෙන් පිටවීමෙන් මකා දැමෙනු ඇත.
einpoklum

11

සමාන පිළිතුරු සඳහා සබැඳිය මෙන්න: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

ස්මාර්ට් පොයින්ටරයක් ​​යනු සාමාන්‍ය දර්ශකයක් ලෙස ක්‍රියා කරන, පෙනෙන සහ දැනෙන නමුත් වැඩි ක්‍රියාකාරීත්වයක් ලබා දෙන වස්තුවකි. C ++ හි, ස්මාර්ට් පොයින්ටර්ස් අච්චු පංති ලෙස ක්‍රියාත්මක වන අතර එය දර්ශකයක් වටකර සම්මත දර්ශක ක්‍රියාකරුවන් අභිබවා යයි. සාමාන්‍ය දර්ශකයන්ට වඩා ඔවුන්ට වාසි ගණනාවක් තිබේ. ඒවා ශුන්‍ය වස්තුවකට ශුන්‍ය දර්ශක හෝ දර්ශක ලෙස ආරම්භ කිරීමට සහතික වේ. ශුන්‍ය දර්ශකයක් හරහා දිශාව පරීක්ෂා කරනු ලැබේ. මකාදැමීම කිසි විටෙකත් අවශ්‍ය නොවේ. වස්තූන් වෙත අවසාන දර්ශකය නැති වූ විට ස්වයංක්‍රීයව නිදහස් වේ. මෙම ස්මාර්ට් පොයින්ටර්ස් හි ඇති එක් වැදගත් ගැටළුවක් නම් සාමාන්‍ය දර්ශකයන් මෙන් නොව ඔවුන් උරුමයට ගරු නොකරන බවයි. බහුමාමක කේතය සඳහා ස්මාර්ට් පොයින්ටර් ආකර්ශනීය නොවේ. ස්මාර්ට් පොයින්ටර් ක්‍රියාත්මක කිරීම සඳහා උදාහරණයක් පහත දැක්වේ.

උදාහරණයක්:

template <class X>
class smart_pointer
{
          public:
               smart_pointer();                          // makes a null pointer
               smart_pointer(const X& x)            // makes pointer to copy of x

               X& operator *( );
               const X& operator*( ) const;
               X* operator->() const;

               smart_pointer(const smart_pointer <X> &);
               const smart_pointer <X> & operator =(const smart_pointer<X>&);
               ~smart_pointer();
          private:
               //...
};

මෙම පන්තිය X වර්ගයේ වස්තුවකට ස්මාර්ට් පොයින්ටරයක් ​​ක්‍රියාත්මක කරයි. වස්තුවම ගොඩවල් මත පිහිටා ඇත. එය භාවිතා කරන ආකාරය මෙන්න:

smart_pointer <employee> p= employee("Harris",1333);

අධි බර පැටවූ ක්‍රියාකරුවන් මෙන්, p ද සාමාන්‍ය දර්ශකයක් මෙන් හැසිරෙනු ඇත,

cout<<*p;
p->raise_salary(0.5);

9

http://en.wikipedia.org/wiki/Smart_pointer

පරිගණක විද්‍යාවේදී, ස්මාර්ට් පොයින්ටරය යනු වියුක්ත දත්ත වර්ගයක් වන අතර එය ස්වයංක්‍රීය කසළ එකතු කිරීම හෝ සීමාවන් පරීක්ෂා කිරීම වැනි අතිරේක විශේෂාංග සපයන අතරම දර්ශකයක් අනුකරණය කරයි. මෙම අතිරේක අංගයන් මඟින් කාර්යක්ෂමතාව රඳවා ගනිමින් දර්ශකයන් අනිසි ලෙස භාවිතා කිරීම නිසා ඇතිවන දෝෂ අවම කිරීමට අදහස් කෙරේ. මතක කළමනාකරණයේ අරමුණු සඳහා ස්මාර්ට් පොයින්ටර්ස් සාමාන්‍යයෙන් ඒවා වෙත යොමු වන වස්තූන් නිරීක්ෂණය කරයි. දර්ශකයන් අනිසි ලෙස භාවිතා කිරීම දෝෂ වල ප්‍රධාන ප්‍රභවයකි: දර්ශක භාවිතා කර ලියා ඇති වැඩසටහනක් මඟින් නිරන්තරයෙන් වෙන් කිරීම, අවලංගු කිරීම සහ යොමු කිරීම මඟින් සමහර මතක කාන්දුවීම් සිදුවීමට ඉඩ ඇත. සම්පත් හුවමාරුව ස්වයංක්‍රීය කිරීම මගින් ස්මාර්ට් පොයින්ටර්ස් මතක කාන්දු වීම වැළැක්වීමට උත්සාහ කරයි: වස්තුවකට දර්ශකය (හෝ දර්ශක මාලාවක අවසාන) විනාශ වූ විට,


6

මෙම නිබන්ධනයේ T පන්තියක් වීමට ඉඩ දෙන්න C ++ හි දර්ශක වර්ග 3 කට බෙදිය හැකිය:

1) අමු දර්ශක :

T a;  
T * _ptr = &a; 

ඔවුන් මතක ස්ථානයක මතක ස්ථානයක තබා ගනී. වැඩසටහන් නිරීක්ෂණය කිරීම දුෂ්කර වන බැවින් ප්‍රවේශමෙන් භාවිතා කරන්න.

ස්ථාවර දත්ත හෝ ලිපිනය සහිත දර්ශක back පසුපසට කියවන්න}

T a ; 
const T * ptr1 = &a ; 
T const * ptr1 = &a ;

නියතයක් වන දත්ත වර්ගයක් වන ටී වෙත යොමු කරන්න. අර්ථය ඔබට දර්ශකය භාවිතා කරමින් දත්ත වර්ගය වෙනස් කළ නොහැක. එනම් *ptr1 = 19; ක්රියා නොකරනු ඇත. නමුත් ඔබට දර්ශකය ගෙන යා හැකිය. එනම් ptr1++ , ptr1--; ආදිය ක්‍රියාත්මක වනු ඇත. පසුපසට කියවන්න: නියත වන T ටයිප් කිරීමට දර්ශකය

  T * const ptr2 ;

දත්ත වර්ගයක් වන ටී. තේරුම ඔබට දර්ශකය චලනය කළ නොහැකි නමුත් දර්ශකය මඟින් පෙන්වා ඇති අගය වෙනස් කළ හැකිය. එනම් *ptr2 = 19වැඩ කරන නමුත් ptr2++ ; ptr2--යනාදිය ක්‍රියා නොකරනු ඇත. පසුපසට කියවන්න: T වර්ගයට const pointer

const T * const ptr3 ; 

සංයුක්ත දත්ත වර්ගයක් වන ටී. තේරුම ඔබට දර්ශකය චලනය කළ නොහැකි අතර දත්ත වර්ග දර්ශකය දර්ශකය ලෙස වෙනස් කළ නොහැක. එනම්. ptr3-- ; ptr3++ ; *ptr3 = 19;ක්රියා නොකරනු ඇත

3) ස්මාර්ට් පොයින්ටර්ස් : { #include <memory>}

බෙදාගත් දර්ශකය :

  T a ; 
     //shared_ptr<T> shptr(new T) ; not recommended but works 
     shared_ptr<T> shptr = make_shared<T>(); // faster + exception safe

     std::cout << shptr.use_count() ; // 1 //  gives the number of " 
things " pointing to it. 
     T * temp = shptr.get(); // gives a pointer to object

     // shared_pointer used like a regular pointer to call member functions
      shptr->memFn();
     (*shptr).memFn(); 

    //
     shptr.reset() ; // frees the object pointed to be the ptr 
     shptr = nullptr ; // frees the object 
     shptr = make_shared<T>() ; // frees the original object and points to new object

දර්ශකය මඟින් පෙන්වා ඇති වස්තුවට “දේවල්” කොපමණ සංඛ්‍යාවක් යොමු වී ඇත්දැයි සොයා බැලීම සඳහා යොමු ගණන් කිරීම භාවිතා කරමින් ක්‍රියාත්මක කිරීම. මෙම ගණනය 0 ට ගිය විට, වස්තුව ස්වයංක්‍රීයව මකා දමනු ලැබේ, එනම් වස්තුව වෙත යොමු කරන සියලුම share_ptr විෂය පථයෙන් බැහැර වූ විට විරෝධය මකා දමනු ලැබේ. මෙය නව භාවිතයෙන් ඔබ වෙන් කර ඇති වස්තු මකා දැමීමේ හිසරදයෙන් මිදෙයි.

දුර්වල දර්ශකය: හවුල් දර්ශකය භාවිතා කරන විට පැන නගින චක්‍රීය යොමු කිරීම් සමඟ කටයුතු කිරීමට උපකාරී වේ ඔබ සතුව හවුල් වස්තු දෙකක් මඟින් පෙන්වා ඇති වස්තු දෙකක් තිබේ නම් සහ එකිනෙකා සමඟ බෙදාගත් දර්ශකය වෙත යොමු වන අභ්‍යන්තර හවුල් දර්ශකයක් තිබේ නම් චක්‍රීය යොමු කිරීමක් ඇති අතර වස්තුව නොපවතිනු ඇත හවුල් දර්ශකයන් විෂය පථයෙන් බැහැර වූ විට මකා දැමෙනු ඇත. මෙය විසඳීම සඳහා, අභ්‍යන්තර සාමාජිකයා shared_ptr සිට දුර්වල_ptr දක්වා වෙනස් කරන්න. සටහන: දුර්වල දර්ශක භාවිත අගුල () මඟින් පෙන්වා ඇති මූලද්‍රව්‍යයට ප්‍රවේශ වීම සඳහා, මෙය දුර්වල_පෝටරයක් ​​ලබා දෙයි.

T a ; 
shared_ptr<T> shr = make_shared<T>() ; 
weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr 
wk.lock()->memFn() ; // use lock to get a shared_ptr 
//   ^^^ Can lead to exception if the shared ptr has gone out of scope
if(!wk.expired()) wk.lock()->memFn() ;
// Check if shared ptr has gone out of scope before access

බලන්න: std :: బలహీన_ptr ප්‍රයෝජනවත් වන්නේ කවදාද?

අද්විතීය දර්ශකය : සුවිශේෂී හිමිකාරිත්වයක් සහිත සැහැල්ලු බර ස්මාර්ට් දර්ශකය. දර්ශකයන් අතර වස්තු බෙදා නොගෙන අද්විතීය වස්තූන් වෙත යොමු කරන විට භාවිතා කරන්න.

unique_ptr<T> uptr(new T);
uptr->memFn(); 

//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr
uptr.reset() ; // deletes the object pointed to by uptr 

අද්විතීය ptr විසින් පෙන්වා ඇති වස්තුව වෙනස් කිරීමට, චලනය වන අර්ථ නිරූපණය භාවිතා කරන්න

unique_ptr<T> uptr1(new T);
unique_ptr<T> uptr2(new T);
uptr2 = std::move(uptr1); 
// object pointed by uptr2 is deleted and 
// object pointed by uptr1 is pointed to by uptr2
// uptr1 becomes null 

යොමුව: ඒවා අත්‍යවශ්‍යයෙන්ම const pointers ලෙස විය හැකිය, එනම් නියතයක් වන අතර එය වඩා හොඳ වාක්‍ය ඛණ්ඩයකින් ගෙන යා නොහැක.

බලන්න: C ++ හි දර්ශක විචල්‍යයක් සහ යොමු විචල්‍යයක් අතර ඇති වෙනස්කම් මොනවාද?

r-value reference : reference to a temporary object   
l-value reference : reference to an object whose address can be obtained
const reference : reference to a data type which is const and cannot be modified 

යොමුව: https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ මෙම ප්‍රශ්නය පෙන්වා දුන් ඇන්ඩ්‍රේට ස්තූතියි.


3

ස්මාර්ට් පොයින්ටරයක් ​​යනු පංතියකි, සාමාන්‍ය දර්ශකයේ එතීමකි. සාමාන්‍ය දර්ශකයන් මෙන් නොව, ස්මාර්ට් පොයින්ට්හි ජීවන කවය පදනම් වී ඇත්තේ යොමු ගණන් කිරීමකි (ස්මාර්ට් පොයින්ටර් වස්තුව කොපමණ වාරයක් පවරා ඇත්ද). එබැවින් ස්මාර්ට් පොයින්ටරයක් ​​වෙනත් එකකට පවරා ඇති විට, අභ්‍යන්තර යොමු ගණන ප්ලස්. වස්තුව විෂය පථයෙන් පිටතට යන සෑම අවස්ථාවකම, යොමු ගණන us ණ us ණ වේ.

ස්වයංක්‍රීය දර්ශකය සමාන වුවත්, ස්මාර්ට් පොයින්ටරයට වඩා සම්පූර්ණයෙන්ම වෙනස් ය. ස්වයංක්‍රීය දර්ශක වස්තුවක් විචල්‍ය විෂය පථයෙන් පිටතට යන සෑම අවස්ථාවකම එය සම්පත අවලංගු කරන පහසු පන්තියකි. යම් දුරකට, එය දර්ශකයක් (ගතිකව වෙන් කරන ලද මතකයට) සිරස් විචල්‍යයකට සමාන ලෙස ක්‍රියා කරයි (සම්පාදනය කරන වේලාවේදී සංඛ්‍යාත්මකව වෙන් කර ඇත).


2

ස්මාර්ට් පොයින්ටර්ස් යනු මතක වෙන් කිරීම, සම්පත් බෙදාගැනීම සහ මාරු කිරීම ගැන ඔබට කරදර විය යුතු නැති ස්ථාන වේ.

ජාවා හි ඕනෑම ප්‍රතිපාදනයක් ක්‍රියාත්මක වන ආකාරයටම ඔබට මෙම දර්ශකය ඉතා හොඳින් භාවිතා කළ හැකිය. ජාවා හි කසළ එකතු කරන්නා උපක්‍රමය කරන අතර ස්මාර්ට් පොයින්ටර්ස් හි උපක්‍රමය ඩිස්ට්‍රැක්ටර්ස් විසින් සිදු කරයි.


1

පවතින පිළිතුරු හොඳයි, නමුත් ස්මාර්ට් පොයින්ටරයක් ​​ඔබ විසඳීමට උත්සාහ කරන ගැටලුවට (සම්පූර්ණ) පිළිතුර නොවන විට කුමක් කළ යුතුද යන්න ආවරණය නොකරන්න.

වෙනත් දේ අතර (වෙනත් පිළිතුරු වලින් හොඳින් පැහැදිලි කර ඇත) ස්මාර්ට් පොයින්ටරයක් ​​භාවිතා කිරීම සඳහා විසඳුමක් වන්නේ ශ්‍රිත ප්‍රතිලාභ වර්ගයක් ලෙස වියුක්ත පන්තියක් අප භාවිතා කරන්නේ කෙසේද? එය මෙම ප්‍රශ්නයේ අනුපිටපතක් ලෙස සලකුණු කර ඇත. කෙසේ වෙතත්, C ++ හි ආපසු වර්ගයක් ලෙස වියුක්ත (හෝ ඇත්ත වශයෙන්ම ඕනෑම) මූලික පංතියක් නියම කිරීමට පෙළඹී ඇත්දැයි ඇසීමට ඇති පළමු ප්‍රශ්නය වන්නේ “ඔබ ඇත්තටම අදහස් කරන්නේ කුමක්ද?”. බූස්ට් පොයින්ටර් බහාලුම් පුස්තකාලයේ ප්‍රලේඛනය තුළ සී ++ හි (සහ මෙය වෙනත් භාෂාවන්ට වෙනස් වන්නේ කෙසේද) හොඳ වචන සාකච්ඡාවක් (වැඩිදුර යොමු කිරීම් සහිතව) ඇත.. සාරාංශයක් ලෙස, C ++ හි ඔබ හිමිකාරිත්වය ගැන සිතා බැලිය යුතුය. කුමන ස්මාර්ට් පොයින්ටර්ස් ඔබට උදව් කරයි, නමුත් එකම විසඳුම නොවේ, හෝ සෑම විටම සම්පූර්ණ විසඳුමක් නොවේ (ඒවා ඔබට බහුමාමක පිටපතක් ලබා නොදේ) සහ සෑම විටම ඔබේ අතුරු මුහුණතේ නිරාවරණය කිරීමට අවශ්‍ය විසඳුමක් නොවේ (සහ ක්‍රියාකාරී ප්‍රතිලාභයක් භයානක ලෙස පෙනේ අතුරු මුහුණතක් වගේ). උදාහරණයක් ලෙස යොමු කිරීමක් ආපසු දීමට එය ප්‍රමාණවත් විය හැකිය. නමුත් මේ සෑම අවස්ථාවකම (ස්මාර්ට් පොයින්ටර්, පොයින්ටර් බහාලුම හෝ යොමු කිරීමක් ආපසු ලබා දීම) ඔබ ආපසු පැමිණීම අගයක සිට යම් ආකාරයක යොමු කිරීමකට වෙනස් කර ඇත. ඔබට ඇත්ත වශයෙන්ම පිටපතක් අවශ්‍ය නම්, ඔබට තවත් බොයිලර් ප්ලේට් “අයිඩියම්” එකතු කිරීමට හෝ සී ++ හි අයිඕපීඑම් (හෝ වෙනත්) ඕඕපී වලින් ඔබ්බට ගොස් ඇඩෝබි පොලි හෝ වැනි පුස්තකාල භාවිතා කරමින් වඩාත් සාමාන්‍ය බහුමාපකයට ගෙන යා බූස්ට් බහුමාපක ඕඕපීයෙන් ඔබ්බට ගමන් කිරීමට අවශ්‍ය විය හැකිය. යුතුය.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.