-5

So I have a struct, and there I would like to access specific values from within it in another method. I am not allowed to modify the struct itself. Here is the struct and a couple of functions that are used to initialize and access it.

struct StdCardConfirmationReceipt
{
private:
    std::string sOfrIdOrderCentral;
    std::string sOrderIdOrderCentral;
    std::string sFulfillmentOrderIdOrderCentral;

public:
    StdCardConfirmationReceipt()
    {       
        sOfrIdOrderCentral = "";
        sOrderIdOrderCentral = "";
        sFulfillmentOrderIdOrderCentral = "";
    }

    StdCardConfirmationReceipt& operator=(const StdCardConfirmationReceipt& source )
    {
        sOfrIdOrderCentral                  = source.sOfrIdOrderCentral;
        sOrderIdOrderCentral                = source.sOrderIdOrderCentral;
        sFulfillmentOrderIdOrderCentral     = source.sFulfillmentOrderIdOrderCentral;
    }

I would like to get these values 'sOFrIDOrderCentral' and sFulfillmentOrdIdOrderCentral' and put it in another struct. Is this possible with the above code? Here is the for-loop I'm using in the other method to access the struct.

for(std::vector<StdCardConfirmationReceipt>::iterator vIter= mvCardConfirmationReceiptList.begin(); vIter != mvCardConfirmationReceiptList.end(); ++vIter)
{
    //need to accesss OFrIDOrderCentral and sFulfillmentOrdIdOrderCentral
}
Saif Ahsanullah
  • 204
  • 3
  • 13
  • 3
    A more *minimal* example would be considerably better here. They're private properties, so make an accessor method. – tadman Apr 06 '16 at 20:10
  • @kfsone All of the data members of the struct are private. – NathanOliver Apr 06 '16 at 20:15
  • For such struct you have not to write consturctor and assign operator. – AnatolyS Apr 06 '16 at 20:16
  • There is no code there that would allow access to those members. – SergeyA Apr 06 '16 at 20:16
  • @NathanOliver, `-pedantic` Not *all the members*, just all of the **data** members :) And for your comment below this - what *pointer trickery* do you have in mind? – SergeyA Apr 06 '16 at 20:19
  • 1
    It is possible with pointer trickery but it is not something you should do. – NathanOliver Apr 06 '16 at 20:19
  • @SergeyA I updated the comment :). To your update see: http://stackoverflow.com/a/3173080/4342498 – NathanOliver Apr 06 '16 at 20:19
  • Will I have to write getter functions to the struct? There are currently setters that set all the data but no getters. example: void setOrderIdOrderCentral(std::string sOrderIdOrderCentral) { this->sOrderIdOrderCentral = sOrderIdOrderCentral; } – Saif Ahsanullah Apr 06 '16 at 20:20
  • Actually, with the code you have here, you could assume they are "". So if by "access" you mean "read", just hard-code "". (I am not very serious here) – Adrian Maire Apr 06 '16 at 20:23

3 Answers3

1

http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html

Essentially you're asking for access to private members. To quote the full source of the link to ensure it doesn't go stale:

#include <iostream>
using namespace std;

template<typename Tag>
struct result {
  /* export it ... */
  typedef typename Tag::type type;
  static type ptr;
};

template<typename Tag>
typename result<Tag>::type result<Tag>::ptr;

template<typename Tag, typename Tag::type p>
struct rob : result<Tag> {
  /* fill it ... */
  struct filler {
    filler() { result<Tag>::ptr = p; }
  };
  static filler filler_obj;
};

template<typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;

struct A {
private:
  void f() {
    std::cout << "proof!" << std::endl;
  }
};

struct Af { typedef void(A::*type)(); };
template class rob<Af, &A::f>;

int main() {
  A a;
  (a.*result<Af>::ptr)();
}

Essentially using this method would achieve what you want. You should not be doing this, however. It breaks encapsulation and creates exceptionally brittle code.

This can cause incredible maintenance headaches and is generally terrible programming practice. The reason your answer has gotten so many downvotes is because it promotes terrible code if you subvert the information hiding mechanisms built into the language.

M2tM
  • 4,415
  • 1
  • 34
  • 43
  • I am still trying to understand this: `template class rob;` How come it is not a compilation error - to access a private member in such way? I mean, which wording from standard allows this? – SergeyA Apr 06 '16 at 20:42
  • No wording in the standard disallows it, certainly. I am not familiar enough with the language standard to quote for you the passages that enable this syntax. With that said, there is the oft quoted passage https://books.google.com/books?id=0klsAQAAQBAJ&pg=PA454&lpg=PA454&dq=C%2B%2B+protects+against+accident+rather+than+deliberate+circumvention+(fraud)&source=bl&ots=S1r6-byH0P&sig=yNtFfzBDL6hCL7W1FtVq4Pkme8Y&hl=en&sa=X&ved=0ahUKEwjk2dKnx4fMAhUNymMKHbnVDSQQ6AEIHTAA#v=onepage&q=C%2B%2B%20protects%20against%20accident%20rather%20than%20deliberate%20circumvention%20(fraud)&f=false – M2tM Apr 11 '16 at 21:45
  • "C++ protects against accident rather than deliberate circumvention (fraud)" -Bjarne Stroustrup – M2tM Apr 11 '16 at 21:46
  • In this particular instance getting the address of a private member function is allowed by the same language rules of getting the address of a regular member function. – M2tM Apr 11 '16 at 21:47
0

Unfortunately, all of those members are private, so they cannot be accessed from outside of the class. You'll need to either write accessor functions:

#include <vector>
#include <iostream>

struct StdCardConfirmationReceipt {
private:
    std::string sOfrIdOrderCentral;
public:
    StdCardConfirmationReceipt() : sOfrIdOrderCentral() {}
    StdCardConfirmationReceipt(std::string s) : sOfrIdOrderCentral(s) {}
public:
    const std::string& getsOfrIdOrderCentral() const { return sOfrIdOrderCentral; }
};

int main() {
    std::vector<StdCardConfirmationReceipt> vec;
    vec.push_back(StdCardConfirmationReceipt("1"));
    vec.push_back(StdCardConfirmationReceipt("2"));
    vec.push_back(StdCardConfirmationReceipt("3"));
    for (auto vIter = vec.begin(); vIter != vec.end(); ++vIter) {
        std::cout << vIter->getsOfrIdOrderCentral();
    }
}

http://ideone.com/kdwyWL

kfsone
  • 23,617
  • 2
  • 42
  • 74
  • I'd prefer a closer relation to the OP's sample. May be something like a `std::map` for holding the _variables_? – πάντα ῥεῖ Apr 06 '16 at 20:23
  • @πάνταῥεῖ there was no map in his question, but I've normalized my answer to his mvce more. – kfsone Apr 06 '16 at 20:35
  • Since you *can* indeed access private members I am downvoting this. The answer to the question of if you *should* is certainly no, but that isn't what was asked. – M2tM Apr 11 '16 at 21:49
-1

If you have a struct with private data members that you want to access, you can always #define private public right before the struct definition and access them as normal. If you can, just use accessor functions as this is extremely bad practice.

fuzzything44
  • 701
  • 4
  • 15
  • 1
    Deliberately invoking undefined behavior is punishable by 6 months of reading Knuth. Upvoter, shame on you. – SergeyA Apr 06 '16 at 20:26
  • What exactly is the undefined behavior here? I know that this is horrible practice, but it should be defined behavior. – fuzzything44 Apr 06 '16 at 20:29
  • By replacing access modifiers, you are changing class definition. Now, if the same header file is included in another translation unit where no such terrible thing was done, you end up with a class which is defined differently in two translation units. Ka-Boom. – SergeyA Apr 06 '16 at 20:34
  • @SergeyA: we all understand that this solution is terribly dangerous and the worse idea. But is it undefined behaviour? – Adrian Maire Apr 06 '16 at 20:36
  • @AdrianMaire, yes it is. See above why. – SergeyA Apr 06 '16 at 20:40
  • @SergeyA: Yes, I read your comment but: 1) your case is not required to happens, 2) The linker could be required to throw an error. 3) The run time could work, just allowing one case to access properties, while the other not. Those 3 cases are not undefined behaviour. That is why I am asking for more reference. Just curiosity :-) – Adrian Maire Apr 06 '16 at 20:52
  • @AdrianMaire, only the first point is somewhat relevant (yes, it might happen the class is only referenced in one translation unit, but why would it be in the .h file than at all?). Your two second points are exact definition of undefined behavior. Linker could be required, but could be not. Code could work runtime, but could refuse to work. This is the essence of undefined behavior. – SergeyA Apr 06 '16 at 20:56