1. Trang chủ
  2. » Công Nghệ Thông Tin

HandBooks Professional Java-C-Scrip-SQL part 64 ppt

6 43 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 6
Dung lượng 20,47 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

The different styles of getting the stored value differ not only in semantics, but also how they return the stored value.. If you pass a pointer argument, you get a pointer to the stored

Trang 1

std::sort(properties.begin(),properties.end());

std::for_each(

properties.begin(),

properties.end(),

print_names);

std::cout << "\n";

std::cout <<

boost::any_cast<std::string>(properties[0].value()) << "\n";

std::cout <<

boost::any_cast<int>(properties[1].value()) << "\n";

std::cout <<

boost::any_cast<double>(properties[2].value()) << "\n";

}

Notice that we didn't have to explicitly create the anys needed for property's constructor That's because any's converting constructor isn't explicit Although constructors taking one argument should typically be declared explicit, any is an exception to the rule Running the program gives us this output

Example of using any for storing properties

A

B

C

Thirty something

30

3.1415

In this example, because the container was sorted, we retrieved the properties by index, and as we knew their respective types beforehand, we didn't need a

try/catch block for the retrieval When retrieving the value of an instance of any, pass the any by const reference to any_cast if a failure indicates a real error

std::string s=boost::any_cast<std::string>(a);

When a failure is not necessarily an error, pass the any by pointer

std::string* ps=boost::any_cast<std::string>(&a);

Trang 2

The different styles of getting the stored value differ not only in semantics, but also how they return the stored value If you pass a pointer argument, you get a pointer

to the stored value; if you pass a const reference argument, you get a copy of the value

If the value type is expensive to copy, pass the any by pointer to avoid copying the value

There's More to any

There are a few more member functions provided by any, such as testing whether

an instance of any is empty or not, and swapping the values of two instances of any The following example shows how to use them

#include <iostream>

#include <string>

#include "boost/any.hpp"

int main() {

std::cout << "Example of using any member functions\n\n";

boost::any a1(100);

boost::any a2(std::string("200"));

boost::any a3;

std::cout << "a3 is ";

if (!a3.empty()) {

std::cout << "not ";

}

std::cout << "empty\n";

a1.swap(a2);

try {

std::string s=boost::any_cast<std::string>(a1);

std::cout << "a1 contains a string: " << s << "\n";

}

catch(boost::bad_any_cast& e) {

std::cout << "I guess a1 doesn't contain a string!\n";

}

if (int* p=boost::any_cast<int>(&a2)) {

std::cout << "a2 seems to have swapped contents with a1: "

<< *p << "\n";

}

else {

Trang 3

std::cout << "Nope, no int in a2\n";

}

if (typeid(int)==a2.type()) {

std::cout << "a2's type_info equals the type_info of int\n";

}

}

Here's the output from running the program

Example of using any member functions

a3 is empty

a1 contains a string: 200

a2 seems to have swapped contents with a1: 100

a2's type_info equals the type_info of int

Let's examine that code more closely To test whether an instance of any contains

a value, we called the member function empty We tested the any a3 like this

std::cout << "a3 is ";

if (!a3.empty()) {

std::cout << "not ";

}

std::cout << "empty\n";

Because we default constructed a3, a3.empty() returns TRue The next thing

is to swap the contents of a1 with a2 You may wonder why you'd want to swap their contents One plausible scenario is when the identities of the any instances are important (swap only exchanges the contained values) Another reason is to avoid copying when you don't need to keep the original value

a1.swap(a2);

Finally, we use the member function type, which returns a const

std::type_ info&, to test if the contained value is of the type int

if (typeid(int)==a2.type()) {

Note that if an any stores a pointer type, that is reflected in the returned

std::type_info

Trang 4

Storing Pointers in any

Often, the test for empty is enough to know whether the object really contains something valid However, if an any might hold a pointer, be extra careful to test the pointer before trying to dereference it Simply testing whether the any is

empty is not enough, because an any is not considered to be empty when it holds a pointer, even if that pointer is null

boost::any a(static_cast<std::string*>(0));

if (!a.empty()) {

try {

std::string* p=boost::any_cast<std::string*>(a);

if (p) {

std::cout << *p;

}

else {

std::cout << "The any contained a null pointer!\n";

}

}

catch(boost::bad_any_cast&) {}

}

A Better WayUsing shared_ptr

Another complication when storing raw pointers in any is the destruction

semantics The any class accepts ownership of the value it stores, because it keeps

an internal copy of the value, which is destroyed together with the any However, destroying a raw pointer doesn't invoke delete or delete[] on it! It only reclaims the memory occupied by the pointer This makes storing a raw pointer in any problematic, so it's a good idea to use smart pointers instead Indeed, using smart pointers (see "Library 1: Smart_ptr 1") is an ideal way to store a pointer to data in an any This solves the problem of making sure that the memory

associated with a contained pointer is properly deleted When the smart pointer is destroyed, it takes appropriate action to ensure the memory and any data in it are properly destroyed By contrast, note that std::auto_ptr is not appropriate This is because auto_ptr doesn't have normal copy semantics; accessing the value in an any would transfer ownership of the memory and any data in it from the any to the returned auto_ptr

Trang 5

Consider the following code

#include <iostream>

#include <string>

#include <algorithm>

#include <vector>

#include "boost/any.hpp"

#include "boost/shared_ptr.hpp"

First, we'll define two classes, A and B, each with operations is_virtual, which

is virtual, and not_virtual, which is not virtual (had it been virtual, the name would be an extremely bad choice) We want to store objects of these types in anys

class A {

public:

virtual ~A() {

std::cout << "A::~A()\n";

}

void not_virtual() {

std::cout << "A::not_virtual()\n";

}

virtual void is_virtual () {

std::cout << "A:: is_virtual ()\n";

}

};

class B : public A {

public:

void not_virtual() {

std::cout << "B::not_virtual()\n";

}

virtual void is_virtual () {

std::cout << "B:: is_virtual ()\n";

}

};

Let's now define a free function, foo, which accepts an argument that is a

reference to any and that examines the any using any_casts to the types that the function knows how to handle If there's no match, the function simply ignores the any and returns It tests for the types shared_ptr<A> and

Trang 6

shared_ptr<B>, respectively, and calls is_virtual (the virtual function) and not_virtual on them

void foo(boost::any& a) {

std::cout << "\n";

// Try boost::shared_ptr<A>

try {

boost::shared_ptr<A> ptr=

boost::any_cast<boost::shared_ptr<A> >(a);

Ngày đăng: 06/07/2014, 03:20