Паўторнае выкарыстанне кода: метады сябар з метадамі, ня сябру

Мне было цікава, якой гэта можна паўторна выкарыстоўваць код метады , якія маюць адпаведны сябра версіі? Напрыклад, у прыведзеным ніжэй прыкладзе, як йоЗотеЬЫпд і initDoSomething метады робяць тыя ж вылічэнні, і таму іх рэалізацыя практычна аднолькавая. Якой бы лепшы спосаб зрабіць такую ​​рэч так, каб паўторна выкарыстоўваць код?

template < typename T >
class CFoo;

template < typename T > CFoo doSomething( double );

template < typename T >
class CFoo{
    public:
        ...
        friend CFoo doSomething< >( double );
        CFoo initDoSomething( double );
};

Любыя прапановы вітаюцца ;-)

What I would like to achieve is something like: myFooObject1 = doSomething(3.0); without needing to necessarily initialize an object or also: myFooObject1.doSomething(3.0);

1
Ці ёсць члены initDoSomething() доступу з CFoo? Калі так, то як гэта можа зрабіць тое ж самае, як DoSomething ()? Калі няма, то чаму яна складаецца?
дададзена аўтар Luchian Grigore, крыніца
Па маім сціплым меркаванні сяброў і шаблоны варта пазбягаць. выкарыстоўваць толькі іх, калі неабходна, і яны робяць лагічны сэнс. Чаму, уласна, вы спрабуеце дасягнуць?
дададзена аўтар Ed Heal, крыніца
Я хацеў бы прапанаваць вам сысці і справа розніцы паміж функцыянальным праграмаваннем і аб'ектна-арыентаваным праграмаваннем, таксама шукаць слова .
дададзена аўтар Ed Heal, крыніца
Whe вам трэба абедзве версіі? Вам не трэба рабіць initDoSomething статычнай функцыі замест гэтага?
дададзена аўтар crazyjul, крыніца
Я абнавіў свой арыгінальны пост растлумачыць тое, што я хацеў бы дасягнуць.
дададзена аўтар Javier, крыніца

2 адказы

Generally speaking, if a function needs to access the private data-members of a class, you should make it a method of the class rather than a friend-function. There are specific instances where you may want to have a friend function, such as with and overloaded version of operator>>, etc., in order to create a common interface between your objects and other standard C++ interfaces such as streams. Another common use of a stand-alone friend function would be for creating a single function interface that will be parameterized in some way, but you want to keep the interface for that function the same (i.e., a single template-function may take multiple different class types, but you want to call that function the same way with any instantiated version). In general though, making functions as friends of a class just so they can access the private data members of a class breaks the entire idea of data encapsulation that classes create for their private data members in the first place.

In your case, you haven't explicitly explained why doSomething has to be a friend and not a method ... as it stands right now, with the function declaration, there doesn't seem to be any reason why it can't be a public method of CFoo. Secondly, if you are trying to initialize a global-state for your doSomething function, you will want to make initDoSomething a static function of the class rather than a method, so that every version of CFoo is initialized for a call to doSomething rather than just a single instance of CFoo. As it stands right now, you would have to initialize every instance of CFoo before it can be used with doSomething. Semantically that doesn't make sense since doSomething creates a CFoo instance before you can call initDoSomething on that instance to initialize it for a call to doSomething.

1
дададзена
« калі функцыя павінна атрымаць доступ да прыватных дадзеных-сябрам класа, вы павінны зрабіць гэта метад класа, а не адзін-функцыі. » Чаму?
дададзена аўтар curiousguy, крыніца
Гэта гучыць для мяне, як вы хочаце ў асноўным функцыю фабрыкі ... гэта пачынаецца пытанне, якая мэта initDoSomething ? Ці з'яўляецца гэта проста функцыя «генератар», што йоЗотеЬЫпд патрабуе, каб стварыць CFoo аб'ект ? Калі так, то яна павінна быць статычным , так як зноў жа, вы не можаце выклікаць метад аб'екта, які яшчэ не быў пабудаваны, калі вы робіце гэта ў самым канструктару (гэта значыць, праз аператары гэта паказальнік) ... Акрамя таго, калі гэта тое, што вы жадаеце, то няма неабходнасці DoSomething , каб быць сябрам-функцыя, так як initDoSomething абвешчаны як .
дададзена аўтар Jason, крыніца
Я абнавіў свой арыгінальны пост, які ілюструе тое, што я хацеў бы дасягнуць.
дададзена аўтар Javier, крыніца

Спосаб дасягнення кодавага паўторнага выкарыстання ў C ++ гэта проста фактар ​​агульнай кода (магчыма параметризованные) агульных функцыі.

У вашым выпадку, я мяркую, што initDoSomething прадастаўляе доступ да прыватных членам (у адваротным выпадку, чаму гэта функцыя члена?). Так ёсць верагоднасць, што ў вашым выпадку, калі ваша агульная функцыя прымае два аргументу і initDoSomething называе яго прапусканнем прыватны элемент (ы) у якасці аргументаў для агульнай функцыі.

0
дададзена
@curiousguy: Так, але <я> чаму Ці аўтар думае, што належыць там? Вы павінны зрабіць члены функцыі толькі ў выпадку неабходнасці, а не калі гэта магчыма.
дададзена аўтар Frerich Raabe, крыніца
@curiousguy: Не; Я маю на ўвазе, што агульны код павінен быць уведзены ў функцыю, якія атрымліваюць неабходныя значэння (напрыклад, прыватных зменныя-членаў) праз аргументы. Такім чынам, гэтыя функцыі не могуць атрымаць доступ да <я> усе прыватнае стан аб'екта (які функцыя сябра можа).
дададзена аўтар Frerich Raabe, крыніца
«<Я> Я мяркую, што initDoSomething доступ да зачыненых членам (у адваротным выпадку, чаму гэта функцыя член?). » Чаму сябра? таму што аўтар здаецца, належыць тут, відавочна.
дададзена аўтар curiousguy, крыніца
Вы маеце на ўвазе, што функцыі павінны быць сябрам, а не членаў? Мае сэнс.
дададзена аўтар curiousguy, крыніца
Вы не пярэчыце, даючы Ілюстрацыяй ваш адказ? Я таксама абнавіў свой арыгінальны пост, які ілюструе тое, што я хацеў бы дасягнуць.
дададзена аўтар Javier, крыніца